Bug 677883 - Bypass deferred message processing for accessible tab windows. Fixes occasional wm_getobject query failures, which must be responded to. r=davidb
authorJim Mathies <jmathies@mozilla.com>
Tue, 11 Oct 2011 11:11:35 -0500
changeset 79909 49ccbc7fd631943e9e9d815c7ac588bea1d5a583
parent 79908 e54779beb70656b56f17dbf1c6163e4c288dff03
child 79910 52103e8ae17e241e78d0231d8160b0478762412f
push id434
push userclegnitto@mozilla.com
push dateWed, 21 Dec 2011 12:10:54 +0000
treeherdermozilla-beta@bddb6ed8dd47 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs677883
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 677883 - Bypass deferred message processing for accessible tab windows. Fixes occasional wm_getobject query failures, which must be responded to. r=davidb
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/msaa/nsWinUtils.cpp
ipc/glue/WindowsMessageLoop.cpp
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -738,16 +738,20 @@ void nsAccessNodeWrap::DoATSpecificProce
   TurnOffNewTabSwitchingForJawsAndWE();
 }
 
 nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible> nsAccessNodeWrap::sHWNDCache;
 
 LRESULT CALLBACK
 nsAccessNodeWrap::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
+  // Note, this window's message handling should not invoke any call that
+  // may result in a cross-process ipc call. Doing so may violate RPC
+  // message semantics.
+
   switch (msg) {
     case WM_GETOBJECT:
     {
       if (lParam == OBJID_CLIENT) {
         nsDocAccessible* document = sHWNDCache.GetWeak(static_cast<void*>(hWnd));
         if (document) {
           IAccessible* msaaAccessible = NULL;
           document->GetNativeInterface((void**)&msaaAccessible); // does an addref
--- a/accessible/src/msaa/nsWinUtils.cpp
+++ b/accessible/src/msaa/nsWinUtils.cpp
@@ -41,16 +41,20 @@
 #include "nsWinUtils.h"
 
 #include "nsIWinAccessNode.h"
 #include "nsRootAccessible.h"
 
 #include "nsArrayUtils.h"
 #include "nsIDocShellTreeItem.h"
 
+// Window property used by ipc related code in identifying accessible
+// tab windows.
+const PRUnichar* kPropNameTabContent = L"AccessibleTabWindow";
+
 HRESULT
 nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
                               long *aIA2ArrayLen)
 {
   *aIA2Array = NULL;
   *aIA2ArrayLen = 0;
 
   if (!aGeckoArray)
@@ -144,24 +148,29 @@ nsWinUtils::RegisterNativeWindow(LPCWSTR
   ::RegisterClassW(&wc);
 }
 
 HWND
 nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
                                int aX, int aY, int aWidth, int aHeight,
                                bool aIsActive)
 {
-  return ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
-                           L"NetscapeDispatchWnd",
-                           WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
-                           aX, aY, aWidth, aHeight,
-                           aParentWnd,
-                           NULL,
-                           GetModuleHandle(NULL),
-                           NULL);
+  HWND hwnd = ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
+                                L"NetscapeDispatchWnd",
+                                WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
+                                aX, aY, aWidth, aHeight,
+                                aParentWnd,
+                                NULL,
+                                GetModuleHandle(NULL),
+                                NULL);
+  if (hwnd) {
+    // Mark this window so that ipc related code can identify it.
+    ::SetPropW(hwnd, kPropNameTabContent, (HANDLE)1);
+  }
+  return hwnd;
 }
 
 void
 nsWinUtils::ShowNativeWindow(HWND aWnd)
 {
   ::ShowWindow(aWnd, SW_SHOW);
 }
 
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -96,16 +96,18 @@ using namespace mozilla::ipc::windows;
  * modal UI related api calls block an RPC in-call in the child. To prevent
  * windows from freezing, and to allow concurrent processing of critical
  * events (such as painting), we spin a native event dispatch loop while
  * these in-calls are blocked.
  */
 
 // pulled from widget's nsAppShell
 extern const PRUnichar* kAppShellEventId;
+// pulled from accessibility's win utils
+extern const PRUnichar* kPropNameTabContent;
 
 namespace {
 
 const wchar_t kOldWndProcProp[] = L"MozillaIPCOldWndProc";
 
 // This isn't defined before Windows XP.
 enum { WM_XP_THEMECHANGED = 0x031A };
 
@@ -374,16 +376,22 @@ WindowIsDeferredWindow(HWND hWnd)
 
   PRUnichar buffer[256] = { 0 };
   int length = GetClassNameW(hWnd, (wchar_t*)buffer, sizeof(buffer) - 1);
   if (length <= 0) {
     NS_WARNING("Failed to get class name!");
     return false;
   }
 
+  // Tab content creates a window that responds to accessible WM_GETOBJECT
+  // calls. This window can safely be ignored.
+  if (::GetPropW(hWnd, kPropNameTabContent)) {
+    return false;
+  }
+
   // Common mozilla windows we must defer messages to.
   nsDependentString className(buffer, length);
   if (StringBeginsWith(className, NS_LITERAL_STRING("Mozilla")) ||
       StringBeginsWith(className, NS_LITERAL_STRING("Gecko")) ||
       className.EqualsLiteral("nsToolkitClass") ||
       className.EqualsLiteral("nsAppShell:EventWindowClass")) {
     return true;
   }