Bug 539061 - 'OOPP: ASSERTION: Received "nonqueued" message 31, 10'. r=jimm.
authorBen Turner <bent.mozilla@gmail.com>
Fri, 15 Jan 2010 12:35:53 -0800
changeset 37300 9446da52c4a9730085b706aa60aa01cb9adb0899
parent 37299 f278332bcc6d6edf64bae7a740356e1468a906be
child 37301 276e30f679fc445d0131f9225f6ba1221ca01883
push idunknown
push userunknown
push dateunknown
reviewersjimm
bugs539061
milestone1.9.3a1pre
Bug 539061 - 'OOPP: ASSERTION: Received "nonqueued" message 31, 10'. r=jimm.
ipc/glue/WindowsMessageLoop.cpp
ipc/glue/WindowsMessageLoop.h
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -168,44 +168,43 @@ ProcessOrDeferMessage(HWND hwnd,
   // Most messages ask for 0 to be returned if the message is processed.
   LRESULT res = 0;
 
   switch (uMsg) {
     // Messages that can be deferred as-is. These must not contain pointers in
     // their wParam or lParam arguments!
     case WM_ACTIVATE:
     case WM_ACTIVATEAPP:
+    case WM_CANCELMODE:
     case WM_CAPTURECHANGED:
     case WM_CHILDACTIVATE:
     case WM_DESTROY:
+    case WM_ENABLE:
     case WM_IME_NOTIFY:
     case WM_IME_SETCONTEXT:
     case WM_KILLFOCUS:
+    case WM_MOUSEWHEEL:
     case WM_NCDESTROY:
     case WM_PARENTNOTIFY:
     case WM_SETFOCUS:
     case WM_SHOWWINDOW: // Intentional fall-through.
     case WM_XP_THEMECHANGED: {
       deferred = new DeferredSendMessage(hwnd, uMsg, wParam, lParam);
       break;
     }
 
+    case WM_DEVICECHANGE:
+    case WM_NCACTIVATE: // Intentional fall-through.
     case WM_SETCURSOR: {
       // Friggin unconventional return value...
       res = TRUE;
       deferred = new DeferredSendMessage(hwnd, uMsg, wParam, lParam);
       break;
     }
 
-    case WM_NCACTIVATE: {
-      res = TRUE;
-      deferred = new DeferredNCActivateMessage(hwnd, uMsg, wParam, lParam);
-      break;
-    }
-
     case WM_MOUSEACTIVATE: {
       res = MA_NOACTIVATE;
       deferred = new DeferredSendMessage(hwnd, uMsg, wParam, lParam);
       break;
     }
 
     // These messages need to use the RedrawWindow function to generate the
     // right kind of message. We can't simply fake them as the MSDN docs say
@@ -232,38 +231,36 @@ ProcessOrDeferMessage(HWND hwnd,
 
     // This message holds a string in its lParam that we must copy.
     case WM_SETTINGCHANGE: {
       deferred = new DeferredSettingChangeMessage(hwnd, uMsg, wParam, lParam);
       break;
     }
 
     // These messages are faked via a call to SetWindowPos.
-    case WM_WINDOWPOSCHANGED: // Intentional fall-through.
-    case WM_WINDOWPOSCHANGING: {
-      UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
-                   SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_DEFERERASE;
-      deferred = new DeferredWindowPosMessage(hwnd, flags);
+    case WM_WINDOWPOSCHANGED: {
+      deferred = new DeferredWindowPosMessage(hwnd, lParam);
       break;
     }
     case WM_NCCALCSIZE: {
       UINT flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
                    SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER |
                    SWP_DEFERERASE | SWP_NOSENDCHANGING;
-      deferred = new DeferredWindowPosMessage(hwnd, flags);
+      deferred = new DeferredWindowPosMessage(hwnd, lParam, true, flags);
       break;
     }
 
     // Messages that are safe to pass to DefWindowProc go here.
     case WM_GETICON:
     case WM_GETMINMAXINFO:
     case WM_GETTEXT:
     case WM_NCHITTEST:
-    case WM_SETICON: // Intentional fall-through.
-    case WM_SYNCPAINT: {
+    case WM_SETICON:
+    case WM_SYNCPAINT: // Intentional fall-through.
+    case WM_WINDOWPOSCHANGING: {
       return DefWindowProc(hwnd, uMsg, wParam, lParam);
     }
 
     // Unknown messages only.
     default: {
 #ifdef DEBUG
       nsCAutoString log("Received \"nonqueued\" message ");
       log.AppendInt(uMsg);
@@ -659,71 +656,53 @@ DeferredSettingChangeMessage::DeferredSe
 
 DeferredSettingChangeMessage::~DeferredSettingChangeMessage()
 {
   if (lParamString) {
     free(lParamString);
   }
 }
 
+DeferredWindowPosMessage::DeferredWindowPosMessage(HWND aHWnd,
+                                                   LPARAM aLParam,
+                                                   bool aUseCustomFlags,
+                                                   UINT aFlags)
+{
+  WINDOWPOS* source = reinterpret_cast<WINDOWPOS*>(aLParam);
+  memcpy(&windowPos, source, sizeof(windowPos));
+  NS_ASSERTION(aHWnd == source->hwnd, "Mismatched hwnds!");
+  if (aUseCustomFlags) {
+    windowPos.flags = aFlags;
+  }
+  else {
+    // Windows sends in some private flags sometimes that we can't simply copy.
+    // Filter here.
+    UINT mask = SWP_ASYNCWINDOWPOS | SWP_DEFERERASE | SWP_DRAWFRAME |
+                SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_NOACTIVATE |
+                SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW |
+                SWP_NOREPOSITION | SWP_NOSENDCHANGING | SWP_NOSIZE |
+                SWP_NOZORDER | SWP_SHOWWINDOW;
+    windowPos.flags &= mask;
+  }
+}
+
 void
 DeferredWindowPosMessage::Run()
 {
-  AssertWindowIsNotNeutered(hWnd);
-  if (!IsWindow(hWnd)) {
+  AssertWindowIsNotNeutered(windowPos.hwnd);
+  if (!IsWindow(windowPos.hwnd)) {
     NS_ERROR("Invalid window!");
     return;
   }
 
+  if (!IsWindow(windowPos.hwndInsertAfter)) {
+    NS_WARNING("ZOrder change cannot be honored");
+    windowPos.hwndInsertAfter = 0;
+    windowPos.flags |= SWP_NOZORDER;
+  }
+
 #ifdef DEBUG
   BOOL ret = 
 #endif
-  SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
+  SetWindowPos(windowPos.hwnd, windowPos.hwndInsertAfter, windowPos.x,
+               windowPos.y, windowPos.cx, windowPos.cy, windowPos.flags);
   NS_ASSERTION(ret, "SetWindowPos failed!");
 }
-
-DeferredNCActivateMessage::DeferredNCActivateMessage(HWND aHWnd,
-                                                     UINT aMessage,
-                                                     WPARAM aWParam,
-                                                     LPARAM aLParam)
-: DeferredSendMessage(aHWnd, aMessage, aWParam, aLParam),
-  region(NULL)
-{
-  NS_ASSERTION(aMessage == WM_NCACTIVATE, "Wrong message!");
-  if (aLParam) {
-    // This is a window that doesn't have a visual style and so lParam is a
-    // handle to an update region. We need to duplicate it.
-    HRGN source = reinterpret_cast<HRGN>(aLParam);
-
-    DWORD dataSize = GetRegionData(source, 0, NULL);
-    if (!dataSize) {
-      NS_ERROR("GetRegionData failed!");
-      return;
-    }
-
-    nsAutoArrayPtr<char> buffer = new char[dataSize];
-    NS_ASSERTION(buffer, "Out of memory!");
-
-    RGNDATA* data = reinterpret_cast<RGNDATA*>(buffer.get());
-
-    dataSize = GetRegionData(source, dataSize, data);
-    if (!dataSize) {
-      NS_ERROR("GetRegionData failed!");
-      return;
-    }
-
-    HRGN tempRegion = ExtCreateRegion(NULL, dataSize, data);
-    if (!tempRegion) {
-      NS_ERROR("ExtCreateRegion failed!");
-      return;
-    }
-
-    region = tempRegion;
-    lParam = reinterpret_cast<LPARAM>(region);
-  }
-}
-
-DeferredNCActivateMessage::~DeferredNCActivateMessage()
-{
-  if (region) {
-    DeleteObject(region);
-  }
-}
--- a/ipc/glue/WindowsMessageLoop.h
+++ b/ipc/glue/WindowsMessageLoop.h
@@ -139,39 +139,23 @@ private:
 };
 
 // This class uses SetWindowPos to fake various size-related messages. Flags
 // passed to the constructor go straight through to SetWindowPos.
 class DeferredWindowPosMessage : public DeferredMessage
 {
 public:
   DeferredWindowPosMessage(HWND aHWnd,
-                           UINT aFlags)
-   : hWnd(aHWnd),
-     flags(aFlags)
-  { }
+                           LPARAM aLParam,
+                           bool aUseCustomFlags = false,
+                           UINT aFlags = 0);
 
   virtual void Run();
 
 private:
-  HWND hWnd;
-  UINT flags;
-};
-
-class DeferredNCActivateMessage : public DeferredSendMessage
-{
-public:
-  DeferredNCActivateMessage(HWND aHWnd,
-                            UINT aMessage,
-                            WPARAM aWParam,
-                            LPARAM aLParam);
-
-  ~DeferredNCActivateMessage();
-
-private:
-  HRGN region;
+  WINDOWPOS windowPos;
 };
 
 } /* namespace windows */
 } /* namespace ipc */
 } /* namespace mozilla */
 
 #endif /* IPC_GLUE_WINDOWSMESSAGELOOP_H */