Bug 1524983 - Make nsFocusManager::Blur() hand off focus one level up only. r=NeilDeakin
authorHenri Sivonen <hsivonen@hsivonen.fi>
Thu, 14 Mar 2019 16:25:33 +0000
changeset 524905 1e165cd680b96372e6eeeea01a9ad3e78a219b01
parent 524904 1a69c88b8863eb5560c69b2f3a7bf24d164a5db5
child 524906 ec16cfd2ee8e2998a8d07e8fd3dd5215ba8b4d55
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersNeilDeakin
bugs1524983
milestone67.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 1524983 - Make nsFocusManager::Blur() hand off focus one level up only. r=NeilDeakin Depends on D22974 Differential Revision: https://phabricator.services.mozilla.com/D22468
dom/ipc/BrowserBridgeChild.cpp
dom/ipc/BrowserBridgeChild.h
dom/ipc/PBrowserBridge.ipdl
dom/ipc/TabParent.cpp
--- a/dom/ipc/BrowserBridgeChild.cpp
+++ b/dom/ipc/BrowserBridgeChild.cpp
@@ -130,14 +130,43 @@ mozilla::ipc::IPCResult BrowserBridgeChi
   if (aCanRaise) {
     flags |= nsIFocusManager::FLAG_RAISE;
   }
 
   fm->SetFocus(owner, flags);
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvMoveFocus(
+    const bool& aForward, const bool& aForDocumentNavigation) {
+  // Adapted from TabParent
+  nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
+  if (!fm) {
+    return IPC_OK();
+  }
+
+  RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
+
+  if (!owner || !owner->OwnerDoc()) {
+    return IPC_OK();
+  }
+
+  RefPtr<Element> dummy;
+
+  uint32_t type =
+      aForward
+          ? (aForDocumentNavigation
+                 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARDDOC)
+                 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD))
+          : (aForDocumentNavigation
+                 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARDDOC)
+                 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARD));
+  fm->MoveFocus(nullptr, owner, type, nsIFocusManager::FLAG_BYKEY,
+                getter_AddRefs(dummy));
+  return IPC_OK();
+}
+
 void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
   mIPCOpen = false;
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/ipc/BrowserBridgeChild.h
+++ b/dom/ipc/BrowserBridgeChild.h
@@ -47,16 +47,19 @@ class BrowserBridgeChild : public PBrows
  protected:
   friend class PBrowserBridgeChild;
 
   mozilla::ipc::IPCResult RecvSetLayersId(
       const mozilla::layers::LayersId& aLayersId);
 
   mozilla::ipc::IPCResult RecvRequestFocus(const bool& aCanRaise);
 
+  mozilla::ipc::IPCResult RecvMoveFocus(const bool& aForward,
+                                        const bool& aForDocumentNavigation);
+
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
   explicit BrowserBridgeChild(nsFrameLoader* aFrameLoader);
   ~BrowserBridgeChild();
 
   mozilla::layers::LayersId mLayersId;
   bool mIPCOpen;
--- a/dom/ipc/PBrowserBridge.ipdl
+++ b/dom/ipc/PBrowserBridge.ipdl
@@ -27,16 +27,22 @@ child:
 
   /**
    * Request that the IPC child / Web parent process move focus to the
    * browser's frame. If canRaise is true, the window can be raised if
    * it is inactive.
    */
   async RequestFocus(bool canRaise);
 
+  /**
+   * When IPC parent / Web child sends this message, the IPC child / Web parent
+   * should move focus to the next or previous focusable element or document.
+   */
+  async MoveFocus(bool forward, bool forDocumentNavigation);
+
 parent:
   // Destroy the remote web browser due to the nsFrameLoader going away.
   async __delete__();
 
   // DocShell messaging.
   async LoadURL(nsCString aSpec);
 
   // Out of process rendering.
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -477,17 +477,24 @@ void TabParent::ActorDestroy(ActorDestro
   if (os) {
     os->NotifyObservers(NS_ISUPPORTS_CAST(nsITabParent*, this),
                         "ipc:browser-destroyed", nullptr);
   }
 }
 
 mozilla::ipc::IPCResult TabParent::RecvMoveFocus(
     const bool& aForward, const bool& aForDocumentNavigation) {
-  nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+  BrowserBridgeParent* bridgeParent = GetBrowserBridgeParent();
+  if (bridgeParent) {
+    mozilla::Unused << bridgeParent->SendMoveFocus(aForward,
+                                                   aForDocumentNavigation);
+    return IPC_OK();
+  }
+
+  nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
   if (fm) {
     RefPtr<Element> dummy;
 
     uint32_t type =
         aForward
             ? (aForDocumentNavigation
                    ? static_cast<uint32_t>(
                          nsIFocusManager::MOVEFOCUS_FORWARDDOC)