Bug 1397426 - Make async tab switcher use new nsITabParent renderLayers function. r=billm
authorMike Conley <mconley@mozilla.com>
Fri, 03 Nov 2017 10:27:35 -0400
changeset 452319 44d6efb9fa693766d667adb95281edbc9954d16d
parent 452318 f77d887fffcb7cef5ddb5c224639496cc77aac75
child 452320 d39683d8f79f01c24b34625988e0ba39535bf587
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1397426
milestone59.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 1397426 - Make async tab switcher use new nsITabParent renderLayers function. r=billm MozReview-Commit-ID: Go2EdMXGwa7
browser/base/content/tabbrowser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4410,26 +4410,36 @@
 
             setTabState(tab, state) {
               this.setTabStateNoAction(tab, state);
 
               let browser = tab.linkedBrowser;
               let {tabParent} = browser.frameLoader;
               if (state == this.STATE_LOADING) {
                 this.assert(!this.minimizedOrFullyOccluded);
-                browser.docShellIsActive = true;
-                if (!tabParent) {
+
+                if (!this.tabbrowser.tabWarmingEnabled) {
+                  browser.docShellIsActive = true;
+                }
+
+                if (tabParent) {
+                  tabParent.renderLayers(true);
+                } else {
                   this.onLayersReady(browser);
                 }
               } else if (state == this.STATE_UNLOADING) {
                 this.unwarmTab(tab);
+                // Setting the docShell to be inactive will also cause it
+                // to stop rendering layers.
                 browser.docShellIsActive = false;
                 if (!tabParent) {
                   this.onLayersCleared(browser);
                 }
+              } else if (state == this.STATE_LOADED) {
+                this.maybeActivateDocShell(tab);
               }
 
               if (!tab.linkedBrowser.isRemoteBrowser) {
                 // setTabState is potentially re-entrant in the non-remote case,
                 // so we must re-get the state for this assertion.
                 let nonRemoteState = this.getTabState(tab);
                 // Non-remote tabs can never stay in the STATE_LOADING
                 // or STATE_UNLOADING states. By the time this function
@@ -4468,16 +4478,20 @@
               let tabIsLoaded = !browser.isRemoteBrowser ||
                                 browser.frameLoader.tabParent.hasPresented;
 
               if (!this.minimizedOrFullyOccluded) {
                 this.log("Initial tab is loaded?: " + tabIsLoaded);
                 this.setTabState(tab, tabIsLoaded ? this.STATE_LOADED
                                                   : this.STATE_LOADING);
               }
+              for (let ppBrowser of this.tabbrowser._printPreviewBrowsers) {
+                let ppTab = this.tabbrowser.getTabForBrowser(ppBrowser);
+                this.setTabState(ppTab, this.STATE_LOADING);
+              }
             },
 
             destroy() {
               if (this.unloadTimer) {
                 this.clearTimer(this.unloadTimer);
                 this.unloadTimer = null;
               }
               if (this.loadTimer) {
@@ -4635,16 +4649,18 @@
                        * the tab switch.
                        */
                       this.tabbrowser.addEventListener("select", () => {
                         this.tabbrowser._adjustFocusAfterTabSwitch(showTab);
                       }, {once: true});
                     } else {
                       this.tabbrowser._adjustFocusAfterTabSwitch(showTab);
                     }
+
+                    this.maybeActivateDocShell(this.requestedTab);
                   }
                 }
 
                 // This doesn't necessarily exist if we're a new window and haven't switched tabs yet
                 if (this.lastVisibleTab)
                   this.lastVisibleTab._visuallySelected = false;
 
                 this.visibleTab._visuallySelected = true;
@@ -4673,16 +4689,39 @@
               // In that case we just overwrite it with a different tab; it's had its chance.
               this.loadingTab = this.requestedTab;
               this.log("Loading tab " + this.tinfo(this.loadingTab));
 
               this.loadTimer = this.setTimer(() => this.onLoadTimeout(), this.TAB_SWITCH_TIMEOUT);
               this.setTabState(this.requestedTab, this.STATE_LOADING);
             },
 
+            maybeActivateDocShell(tab) {
+              // If we've reached the point where the requested tab has entered
+              // the loaded state, but the DocShell is still not yet active, we
+              // should activate it.
+              let browser = tab.linkedBrowser;
+              let state = this.getTabState(tab);
+              let canCheckDocShellState = !browser.mDestroyed &&
+                                          (browser.docShell ||
+                                           browser.frameLoader.tabParent);
+              if (tab == this.requestedTab &&
+                  canCheckDocShellState &&
+                  state == this.STATE_LOADED &&
+                  !browser.docShellIsActive &&
+                  !this.minimizedOrFullyOccluded) {
+                browser.docShellIsActive = true;
+                this.logState("Set requested tab docshell to active and preserveLayers to false");
+                // If we minimized the window before the switcher was activated,
+                // we might have set the preserveLayers flag for the current
+                // browser. Let's clear it.
+                browser.preserveLayers(false);
+              }
+            },
+
             // This function runs before every event. It fixes up the state
             // to account for closed tabs.
             preActions() {
               this.assert(this.tabbrowser._switcher);
               this.assert(this.tabbrowser._switcher === this);
 
               for (let [tab, ] of this.tabState) {
                 if (!tab.linkedBrowser) {
@@ -4989,17 +5028,22 @@
             shouldActivateDocShell(browser) {
               let tab = this.tabbrowser.getTabForBrowser(browser);
               let state = this.getTabState(tab);
               return state == this.STATE_LOADING || state == this.STATE_LOADED;
             },
 
             activateBrowserForPrintPreview(browser) {
               let tab = this.tabbrowser.getTabForBrowser(browser);
-              this.setTabState(tab, this.STATE_LOADING);
+              let state = this.getTabState(tab);
+              if (state != this.STATE_LOADING &&
+                  state != this.STATE_LOADED) {
+                this.setTabState(tab, this.STATE_LOADING);
+                this.logState("Activated browser " + this.tinfo(tab) + " for print preview");
+              }
             },
 
             canWarmTab(tab) {
               if (!this.tabbrowser.tabWarmingEnabled) {
                 return false;
               }
 
               // If the tab is not yet inserted, closing, not remote,