Bug 1397426 - Add hasLayers to nsITabParent and use it in the async tab switcher. r=billm draft
authorMike Conley <mconley@mozilla.com>
Fri, 17 Nov 2017 09:55:29 -0800
changeset 715462 4b1e2fb945f1dc4591c56f836a1caa9adeea9eb4
parent 715461 874f112e4368a037b4baf02f205198c0f598b5b8
child 715463 4ca9f692635e3a3a1ec8e626d0db24f2e512ec9a
push id94165
push usermconley@mozilla.com
push dateWed, 03 Jan 2018 23:25:52 +0000
reviewersbillm
bugs1397426
milestone59.0a1
Bug 1397426 - Add hasLayers to nsITabParent and use it in the async tab switcher. r=billm This is necessary because sometimes the async tab switcher will instantiate when there already exists some background tabs that are rendering via print preview. When that happens, it's important for the state to be set correctly for them so that we don't accidentally treat them as still loading, and wait (forever) for them to report having finished loading. MozReview-Commit-ID: 2dwo5WlXlgJ
browser/base/content/tabbrowser.xml
dom/interfaces/base/nsITabParent.idl
dom/ipc/TabParent.cpp
toolkit/content/widgets/browser.xml
toolkit/content/widgets/remote-browser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4462,17 +4462,19 @@
 
               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);
+                let state = ppBrowser.hasLayers ? this.STATE_LOADED
+                                                : this.STATE_LOADING;
+                this.setTabState(ppTab, state);
               }
             },
 
             destroy() {
               if (this.unloadTimer) {
                 this.clearTimer(this.unloadTimer);
                 this.unloadTimer = null;
               }
--- a/dom/interfaces/base/nsITabParent.idl
+++ b/dom/interfaces/base/nsITabParent.idl
@@ -28,16 +28,22 @@ interface nsITabParent : nsISupports
    * When aEnabled is set to true, this tells the child to paint and
    * upload layers to the compositor. When aEnabled is set to false,
    * previous layers are cleared from the compositor, but only if
    * preserveLayers is also set to false.
    */
   void renderLayers(in bool aEnabled);
 
   /**
+   * True if layers are being rendered and the compositor has reported
+   * receiving them.
+   */
+  readonly attribute boolean hasLayers;
+
+  /**
    * Whether this tabParent is in prerender mode.
    */
   [infallible] readonly attribute boolean isPrerendered;
 
   /**
    * As an optimisation, setting the docshell's active state to
    * inactive also triggers a layer invalidation to free up some
    * potentially unhelpful memory usage. Calling preserveLayers
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2990,16 +2990,23 @@ TabParent::RenderLayers(bool aEnabled)
     ContentParent* cp = Manager()->AsContentParent();
     cp->ForceTabPaint(this, mLayerTreeEpoch);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+TabParent::GetHasLayers(bool* aResult)
+{
+  *aResult = mHasLayers;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 TabParent::PreserveLayers(bool aPreserveLayers)
 {
   mPreserveLayers = aPreserveLayers;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabParent::SuppressDisplayport(bool aEnabled)
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -299,16 +299,24 @@
 
       <method name="preserveLayers">
         <parameter name="preserve"/>
         <body>
           // Only useful for remote browsers.
         </body>
       </method>
 
+      <property name="hasLayers" readonly="true">
+        <getter>
+          <![CDATA[
+            return this.docShellIsActive;
+          ]]>
+        </getter>
+      </property>
+
       <property name="imageDocument"
                 readonly="true">
         <getter>
           <![CDATA[
             var document = this.contentDocument;
             if (!document || !(document instanceof Components.interfaces.nsIImageDocument))
               return null;
 
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -255,16 +255,26 @@
         <body><![CDATA[
           let {frameLoader} = this;
           if (frameLoader.tabParent) {
             frameLoader.tabParent.preserveLayers(preserve);
           }
         ]]></body>
       </method>
 
+      <property name="hasLayers" readonly="true">
+        <getter><![CDATA[
+          let {frameLoader} = this;
+          if (frameLoader.tabParent) {
+            return frameLoader.tabParent.hasLayers;
+          }
+          return false;
+        ]]></getter>
+      </property>
+
       <field name="_manifestURI"/>
       <property name="manifestURI"
                 onget="return this._manifestURI"
                 readonly="true"/>
 
       <field name="mDestroyed">false</field>
 
       <field name="_permitUnloadId">0</field>