Bug 1407475: Fix IAccessible::accNavigate(NAVRELATION_EMBEDS) for e10s. r=surkov draft
authorJames Teh <jteh@mozilla.com>
Wed, 11 Oct 2017 15:30:22 +1000
changeset 679812 ebe33b0ad3b615ad4b0363a00402dbdc2033a41b
parent 678275 e897e367d3bd489422d86fbdfac54925c18329d2
child 735683 6e38796b174540eec7c7cbf9e1e546981185d1bd
push id84313
push userbmo:jteh@mozilla.com
push dateFri, 13 Oct 2017 03:16:48 +0000
reviewerssurkov
bugs1407475
milestone58.0a1
Bug 1407475: Fix IAccessible::accNavigate(NAVRELATION_EMBEDS) for e10s. r=surkov When we only have a single process, this can be (and was previously) handled the same way as any other relation. However, for multi process, the normal relation mechanism doesn't work because it can't handle remote objects. This patch overrides accNavigate for the root accessible to handle this, since this is only ever used on the root. MozReview-Commit-ID: JLm5zITfG6Y
accessible/windows/msaa/RootAccessibleWrap.cpp
accessible/windows/msaa/RootAccessibleWrap.h
--- a/accessible/windows/msaa/RootAccessibleWrap.cpp
+++ b/accessible/windows/msaa/RootAccessibleWrap.cpp
@@ -97,8 +97,52 @@ RootAccessibleWrap::DocumentActivated(Do
       HWND childDocHWND = static_cast<HWND>(childDoc->GetNativeWindow());
       if (childDoc != aDocument)
         nsWinUtils::HideNativeWindow(childDocHWND);
       else
         nsWinUtils::ShowNativeWindow(childDocHWND);
     }
   }
 }
+
+STDMETHODIMP
+RootAccessibleWrap::accNavigate(
+      /* [in] */ long navDir,
+      /* [optional][in] */ VARIANT varStart,
+      /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
+{
+  // Special handling for NAVRELATION_EMBEDS.
+  // When we only have a single process, this can be handled the same way as
+  // any other relation.
+  // However, for multi process, the normal relation mechanism doesn't work
+  // because it can't handle remote objects.
+  if (navDir != NAVRELATION_EMBEDS ||
+      varStart.vt != VT_I4  || varStart.lVal != CHILDID_SELF) {
+    // We only handle EMBEDS on the root here.
+    // Forward to the base implementation.
+    return DocAccessibleWrap::accNavigate(navDir, varStart, pvarEndUpAt);
+  }
+
+  if (!pvarEndUpAt) {
+    return E_INVALIDARG;
+  }
+
+  Accessible* target = nullptr;
+  // Get the document in the active tab.
+  ProxyAccessible* docProxy = GetPrimaryRemoteTopLevelContentDoc();
+  if (docProxy) {
+    target = WrapperFor(docProxy);
+  } else {
+    // The base implementation could handle this, but we may as well
+    // just handle it here.
+    Relation rel = RelationByType(RelationType::EMBEDS);
+    target = rel.Next();
+  }
+
+  if (!target) {
+    return E_FAIL;
+  }
+
+  VariantInit(pvarEndUpAt);
+  pvarEndUpAt->pdispVal = NativeAccessible(target);
+  pvarEndUpAt->vt = VT_DISPATCH;
+  return S_OK;
+}
--- a/accessible/windows/msaa/RootAccessibleWrap.h
+++ b/accessible/windows/msaa/RootAccessibleWrap.h
@@ -33,16 +33,21 @@ public:
   already_AddRefed<IUnknown> Aggregate(IUnknown* aOuter);
 
   /**
    * @return This object's own IUnknown, as opposed to its wrapper's IUnknown
    *         which is what would be returned by QueryInterface(IID_IUnknown).
    */
   already_AddRefed<IUnknown> GetInternalUnknown();
 
+  virtual /* [id] */ HRESULT STDMETHODCALLTYPE accNavigate(
+    /* [in] */ long navDir,
+    /* [optional][in] */ VARIANT varStart,
+    /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt) override;
+
 private:
   // DECLARE_AGGREGATABLE declares the internal IUnknown methods as well as
   // mInternalUnknown.
   DECLARE_AGGREGATABLE(RootAccessibleWrap);
   IUnknown* mOuter;
 };
 
 } // namespace a11y