Bug 1261842 - Make initial browser remote sooner if we're defaulting to using remote tabs. r=felipe draft
authorMike Conley <mconley@mozilla.com>
Wed, 08 Jun 2016 17:03:42 -0400
changeset 390198 9c77d9e6d4f7f22215430ba29386576b3ee54fca
parent 390197 05473ad2723e1b538e35a9c6f782894e0a2fb9a0
child 390199 571556040b071a2d82cf451fa31b914a975befc1
push id23619
push usermconley@mozilla.com
push dateWed, 20 Jul 2016 20:10:09 +0000
reviewersfelipe
bugs1261842
milestone50.0a1
Bug 1261842 - Make initial browser remote sooner if we're defaulting to using remote tabs. r=felipe MozReview-Commit-ID: 9KVzuOkJFpW
browser/base/content/browser.js
xpfe/appshell/nsIXULBrowserWindow.idl
xpfe/appshell/nsXULWindow.cpp
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -909,16 +909,40 @@ function RedirectLoad({ target: browser,
       }
     };
     Services.obs.addObserver(delayedStartupFinished,
                              "browser-delayed-startup-finished",
                              false);
   }
 }
 
+addEventListener("DOMContentLoaded", function onDCL() {
+  removeEventListener("DOMContentLoaded", onDCL);
+
+  // There are some windows, like macBrowserOverlay.xul, that
+  // load browser.js, but never load tabbrowser.xml. We can ignore
+  // those cases.
+  if (!gBrowser || !gBrowser.updateBrowserRemoteness) {
+    return;
+  }
+
+  window.QueryInterface(Ci.nsIInterfaceRequestor)
+        .getInterface(nsIWebNavigation)
+        .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
+        .QueryInterface(Ci.nsIInterfaceRequestor)
+        .getInterface(Ci.nsIXULWindow)
+        .XULBrowserWindow = window.XULBrowserWindow;
+  window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
+    new nsBrowserAccess();
+
+  let initBrowser =
+    document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
+  gBrowser.updateBrowserRemoteness(initBrowser, gMultiProcessBrowser);
+});
+
 var gBrowserInit = {
   delayedStartupFinished: false,
 
   onLoad: function() {
     gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
 
     Services.obs.addObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed", false);
 
@@ -939,29 +963,21 @@ var gBrowserInit = {
     RefreshBlocker.init();
 
     let mm = window.getGroupMessageManager("browsers");
     mm.loadFrameScript("chrome://browser/content/tab-content.js", true);
     mm.loadFrameScript("chrome://browser/content/content.js", true);
     mm.loadFrameScript("chrome://browser/content/content-UITour.js", true);
     mm.loadFrameScript("chrome://global/content/manifestMessages.js", true);
 
-    window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
-
     // initialize observers and listeners
     // and give C++ access to gBrowser
     XULBrowserWindow.init();
-    window.QueryInterface(Ci.nsIInterfaceRequestor)
-          .getInterface(nsIWebNavigation)
-          .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
-          .QueryInterface(Ci.nsIInterfaceRequestor)
-          .getInterface(Ci.nsIXULWindow)
-          .XULBrowserWindow = window.XULBrowserWindow;
-    window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
-      new nsBrowserAccess();
+
+    window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
 
     if (!gMultiProcessBrowser) {
       // There is a Content:Click message manually sent from content.
       Cc["@mozilla.org/eventlistenerservice;1"]
         .getService(Ci.nsIEventListenerService)
         .addSystemEventListener(gBrowser, "click", contentAreaClick, true);
     }
 
@@ -1098,33 +1114,38 @@ var gBrowserInit = {
           window.arguments[0] = null;
         }
 
         // Stop the about:blank load
         gBrowser.stop();
         // make sure it has a docshell
         gBrowser.docShell;
 
+        // We must set usercontextid before updateBrowserRemoteness()
+        // so that the newly created remote tab child has correct usercontextid
+        if (tabToOpen.hasAttribute("usercontextid")) {
+          let usercontextid = tabToOpen.getAttribute("usercontextid");
+          gBrowser.selectedBrowser.setAttribute("usercontextid", usercontextid);
+        }
+
         // If the browser that we're swapping in was remote, then we'd better
         // be able to support remote browsers, and then make our selectedTab
         // remote.
         try {
           if (tabToOpen.linkedBrowser.isRemoteBrowser) {
             if (!gMultiProcessBrowser) {
               throw new Error("Cannot drag a remote browser into a window " +
                               "without the remote tabs load context.");
             }
-
-            // We must set usercontextid before updateBrowserRemoteness()
-            // so that the newly created remote tab child has correct usercontextid
-            if (tabToOpen.hasAttribute("usercontextid")) {
-              let usercontextid = tabToOpen.getAttribute("usercontextid");
-              gBrowser.selectedBrowser.setAttribute("usercontextid", usercontextid);
-            }
             gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, true);
+          } else if (gBrowser.selectedBrowser.isRemoteBrowser) {
+            // If the browser is remote, then it's implied that
+            // gMultiProcessBrowser is true. We need to flip the remoteness
+            // of this tab to false in order for the tab drag to work.
+            gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, false);
           }
           gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToOpen);
         } catch(e) {
           Cu.reportError(e);
         }
       }
       // window.arguments[2]: referrer (nsIURI | string)
       //                 [3]: postData (nsIInputStream)
@@ -4193,20 +4214,25 @@ var XULBrowserWindow = {
 
   setJSStatus: function () {
     // unsupported
   },
 
   forceInitialBrowserRemote: function() {
     let initBrowser =
       document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
-    gBrowser.updateBrowserRemoteness(initBrowser, true);
     return initBrowser.frameLoader.tabParent;
   },
 
+  forceInitialBrowserNonRemote: function() {
+    let initBrowser =
+      document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
+    gBrowser.updateBrowserRemoteness(initBrowser, false);
+  },
+
   setDefaultStatus: function (status) {
     this.defaultStatus = status;
     this.updateStatusField();
   },
 
   setOverLink: function (url, anchorElt) {
     // Encode bidirectional formatting characters.
     // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
--- a/xpfe/appshell/nsIXULBrowserWindow.idl
+++ b/xpfe/appshell/nsIXULBrowserWindow.idl
@@ -43,16 +43,17 @@ interface nsIXULBrowserWindow : nsISuppo
 
   /**
    * Find the initial browser of the window and set its remote attribute.
    * This can be used to ensure that there is a remote browser in a new
    * window when it first spawns.
    *
    */
   nsITabParent forceInitialBrowserRemote();
+  void forceInitialBrowserNonRemote();
 
   /**
    * Determines whether a load should continue.
    *
    * @param aDocShell
    *        The docshell performing the load.
    * @param aURI
    *        The URI being loaded.
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -1916,17 +1916,17 @@ NS_IMETHODIMP nsXULWindow::CreateNewCont
     AutoNoJSAPI nojsapi;
     nsIThread *thread = NS_GetCurrentThread();
     while (xulWin->IsLocked()) {
       if (!NS_ProcessNextEvent(thread))
         break;
     }
   }
 
-  NS_ENSURE_STATE(xulWin->mPrimaryContentShell);
+  NS_ENSURE_STATE(xulWin->mPrimaryContentShell || xulWin->mPrimaryTabParent);
 
   *_retval = newWindow;
   NS_ADDREF(*_retval);
 
   return NS_OK;
 }
 
 void nsXULWindow::EnableParent(bool aEnable)