Bug 1533716 - Make out-of-process iframes able to request focus. r=masayuki,NeilDeakin
authorHenri Sivonen <hsivonen@hsivonen.fi>
Thu, 14 Mar 2019 16:20:51 +0000
changeset 521906 1a69c88b8863eb5560c69b2f3a7bf24d164a5db5
parent 521905 06e4be63178cf9c50b929533d19b465da6b3c3a7
child 521907 1e165cd680b96372e6eeeea01a9ad3e78a219b01
push id10870
push usernbeleuzu@mozilla.com
push dateFri, 15 Mar 2019 20:00:07 +0000
treeherdermozilla-beta@c594aee5b7a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, NeilDeakin
bugs1533716
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 1533716 - Make out-of-process iframes able to request focus. r=masayuki,NeilDeakin Depends on D22969 Differential Revision: https://phabricator.services.mozilla.com/D22974
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
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/BrowserBridgeChild.h"
+#include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsFrameLoaderOwner.h"
 #include "nsQueryObject.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace dom {
@@ -106,14 +107,37 @@ BrowserBridgeChild* BrowserBridgeChild::
 
 IPCResult BrowserBridgeChild::RecvSetLayersId(
     const mozilla::layers::LayersId& aLayersId) {
   MOZ_ASSERT(!mLayersId.IsValid() && aLayersId.IsValid());
   mLayersId = aLayersId;
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult BrowserBridgeChild::RecvRequestFocus(
+    const bool& aCanRaise) {
+  // 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();
+  }
+
+  uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
+  if (aCanRaise) {
+    flags |= nsIFocusManager::FLAG_RAISE;
+  }
+
+  fm->SetFocus(owner, flags);
+  return IPC_OK();
+}
+
 void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
   mIPCOpen = false;
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/ipc/BrowserBridgeChild.h
+++ b/dom/ipc/BrowserBridgeChild.h
@@ -45,16 +45,18 @@ class BrowserBridgeChild : public PBrows
   static BrowserBridgeChild* GetFrom(nsIContent* aContent);
 
  protected:
   friend class PBrowserBridgeChild;
 
   mozilla::ipc::IPCResult RecvSetLayersId(
       const mozilla::layers::LayersId& aLayersId);
 
+  mozilla::ipc::IPCResult RecvRequestFocus(const bool& aCanRaise);
+
   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
@@ -20,16 +20,23 @@ namespace dom {
  * PBrowserBridge corresponds to a remote iframe.
  */
 async protocol PBrowserBridge {
   manager PBrowser;
 
 child:
   async SetLayersId(LayersId layersId);
 
+  /**
+   * 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);
+
 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
@@ -1890,16 +1890,22 @@ mozilla::ipc::IPCResult TabParent::RecvO
   // plugin process of the key event's result.
   bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED);
   HandledWindowedPluginKeyEvent(aKeyEventData, consumed);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult TabParent::RecvRequestFocus(const bool& aCanRaise) {
+  BrowserBridgeParent* bridgeParent = GetBrowserBridgeParent();
+  if (bridgeParent) {
+    mozilla::Unused << bridgeParent->SendRequestFocus(aCanRaise);
+    return IPC_OK();
+  }
+
   nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
   if (!fm) {
     return IPC_OK();
   }
 
   if (!mFrameElement || !mFrameElement->OwnerDoc()) {
     return IPC_OK();
   }