Bug 1427304: Return the oleacc window accessible for the outer HWND of windows created with popup=yes. r=yzen
authorJames Teh <jteh@mozilla.com>
Fri, 29 May 2020 14:16:14 +0000
changeset 533096 f65636dc2b12ab0480672a418adccc64219d8d7a
parent 533095 9b06c0ec158c0e11f6cd05349a44e3ba0cd62a20
child 533097 9ac6f9017b79ba070f7cb5c5dc1e82f0c6734f93
push id37462
push usermalexandru@mozilla.com
push dateSat, 30 May 2020 09:46:43 +0000
treeherdermozilla-central@8aaca63ec5c6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1427304
milestone78.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 1427304: Return the oleacc window accessible for the outer HWND of windows created with popup=yes. r=yzen Differential Revision: https://phabricator.services.mozilla.com/D77442
accessible/windows/msaa/AccessibleWrap.cpp
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -206,16 +206,39 @@ AccessibleWrap::get_accParent(IDispatch 
   DocAccessible* doc = AsDoc();
   if (doc) {
     // Return window system accessible object for root document and tab document
     // accessibles.
     if (!doc->ParentDocument() ||
         (nsWinUtils::IsWindowEmulationStarted() &&
          nsCoreUtils::IsTabDocument(doc->DocumentNode()))) {
       HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
+      if (XRE_IsParentProcess() && hwnd && !doc->ParentDocument()) {
+        nsIFrame* frame = GetFrame();
+        if (frame) {
+          nsIWidget* widget = frame->GetNearestWidget();
+          if (widget->WindowType() == eWindowType_child &&
+              !widget->GetParent()) {
+            // Bug 1427304: Windows opened with popup=yes (such as the WebRTC
+            // sharing indicator) get two HWNDs. The root widget is associated
+            // with the inner HWND, but the outer HWND still answers to
+            // WM_GETOBJECT queries. This means that getting the parent of the
+            // oleacc window accessible for the inner HWND returns this
+            // root accessible. Thus, to avoid a loop, we must never return the
+            // oleacc window accessible for the inner HWND. Instead, we use the
+            // outer HWND here.
+            HWND parentHwnd = ::GetParent(hwnd);
+            if (parentHwnd) {
+              MOZ_ASSERT(::GetWindowLongW(parentHwnd, GWL_STYLE) & WS_POPUP,
+                         "Parent HWND should be a popup!");
+              hwnd = parentHwnd;
+            }
+          }
+        }
+      }
       if (hwnd &&
           SUCCEEDED(::AccessibleObjectFromWindow(
               hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent))) {
         return S_OK;
       }
     }
   }