Bug 1397426 - Expose renderLayers state via nsITabParent and lazily retrieve initial tab states in async tab switcher. r=billm
MozReview-Commit-ID: IIMmwrgJUV6
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4372,18 +4372,30 @@
clearTimer(timer) {
timer.cancel();
},
getTabState(tab) {
let state = this.tabState.get(tab);
if (state === undefined) {
- return this.STATE_UNLOADED;
- }
+ state = this.STATE_UNLOADED;
+
+ if (tab && tab.linkedPanel) {
+ let b = tab.linkedBrowser;
+ if (b.renderLayers && b.hasLayers) {
+ state = this.STATE_LOADED;
+ } else if (b.renderLayers && !b.hasLayers) {
+ state = this.STATE_LOADING;
+ } else if (!b.renderLayers && b.hasLayers) {
+ state = this.STATE_UNLOADING;
+ }
+ }
+ }
+
return state;
},
setTabStateNoAction(tab, state) {
if (state == this.STATE_UNLOADED) {
this.tabState.delete(tab);
} else {
this.tabState.set(tab, state);
@@ -4398,17 +4410,17 @@
if (state == this.STATE_LOADING) {
this.assert(!this.minimizedOrFullyOccluded);
if (!this.tabbrowser.tabWarmingEnabled) {
browser.docShellIsActive = true;
}
if (tabParent) {
- tabParent.renderLayers(true);
+ browser.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;
@@ -4436,39 +4448,42 @@
get minimizedOrFullyOccluded() {
return window.windowState == window.STATE_MINIMIZED ||
window.isFullyOccluded;
},
init() {
this.log("START");
- // 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.
- this.tabbrowser.mCurrentBrowser.preserveLayers(false);
-
window.addEventListener("MozAfterPaint", this);
window.addEventListener("MozLayerTreeReady", this);
window.addEventListener("MozLayerTreeCleared", this);
window.addEventListener("TabRemotenessChange", this);
window.addEventListener("sizemodechange", this);
window.addEventListener("occlusionstatechange", this);
window.addEventListener("SwapDocShells", this, true);
window.addEventListener("EndSwapDocShells", this, true);
- let tab = this.requestedTab;
- let browser = tab.linkedBrowser;
- let tabIsLoaded = browser.renderingLayers;
+ let initialTab = this.requestedTab;
+ let initialBrowser = initialTab.linkedBrowser;
+
+ let tabIsLoaded = !initialBrowser.isRemoteBrowser ||
+ initialBrowser.frameLoader.tabParent.hasLayers;
+
+ // 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.
+ initialBrowser.preserveLayers(false);
if (!this.minimizedOrFullyOccluded) {
this.log("Initial tab is loaded?: " + tabIsLoaded);
- this.setTabState(tab, tabIsLoaded ? this.STATE_LOADED
- : this.STATE_LOADING);
- }
+ this.setTabState(initialTab, tabIsLoaded ? this.STATE_LOADED
+ : this.STATE_LOADING);
+ }
+
for (let ppBrowser of this.tabbrowser._printPreviewBrowsers) {
let ppTab = this.tabbrowser.getTabForBrowser(ppBrowser);
let state = ppBrowser.hasLayers ? this.STATE_LOADED
: this.STATE_LOADING;
this.setTabState(ppTab, state);
}
},
--- a/dom/interfaces/base/nsITabParent.idl
+++ b/dom/interfaces/base/nsITabParent.idl
@@ -20,22 +20,21 @@ interface nsITabParent : nsISupports
* Manages the docshell active state of the remote browser. Setting the
* docShell to be active will also cause it to render layers and upload
* them to the compositor. Setting the docShell as not active will clear
* those layers.
*/
attribute boolean docShellIsActive;
/**
- * 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.
+ * When set to true, this tells the child to paint and upload layers to
+ * the compositor. When set to false, previous layers are cleared from
+ * the compositor, but only if preserveLayers is also set to false.
*/
- void renderLayers(in bool aEnabled);
+ attribute boolean renderLayers;
/**
* True if layers are being rendered and the compositor has reported
* receiving them.
*/
readonly attribute boolean hasLayers;
/**
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2902,17 +2902,17 @@ TabParent::GetUseAsyncPanZoom(bool* useA
// defined in nsITabParent
NS_IMETHODIMP
TabParent::SetDocShellIsActive(bool isActive)
{
// docshell is consider prerendered only if not active yet
mIsPrerendered &= !isActive;
mDocShellIsActive = isActive;
- RenderLayers(isActive);
+ SetRenderLayers(isActive);
Unused << SendSetDocShellIsActive(isActive);
// update active accessible documents on windows
#if defined(XP_WIN) && defined(ACCESSIBILITY)
if (a11y::Compatibility::IsDolphin()) {
if (a11y::DocAccessibleParent* tabDoc = GetTopLevelDocAccessible()) {
HWND window = tabDoc->GetEmulatedWindowHandle();
MOZ_ASSERT(window);
@@ -2944,17 +2944,17 @@ TabParent::GetDocShellIsActive(bool* aIs
NS_IMETHODIMP
TabParent::GetIsPrerendered(bool* aIsPrerendered)
{
*aIsPrerendered = mIsPrerendered;
return NS_OK;
}
NS_IMETHODIMP
-TabParent::RenderLayers(bool aEnabled)
+TabParent::SetRenderLayers(bool aEnabled)
{
if (aEnabled == mRenderLayers) {
if (aEnabled && mHasLayers && mPreserveLayers) {
// RenderLayers might be called when we've been preserving layers,
// and already had layers uploaded. In that case, the MozLayerTreeReady
// event will not naturally arrive, which can confuse the front-end
// layer. So we fire the event here.
RefPtr<TabParent> self = this;
@@ -2990,16 +2990,23 @@ TabParent::RenderLayers(bool aEnabled)
ContentParent* cp = Manager()->AsContentParent();
cp->ForceTabPaint(this, mLayerTreeEpoch);
}
return NS_OK;
}
NS_IMETHODIMP
+TabParent::GetRenderLayers(bool* aResult)
+{
+ *aResult = mRenderLayers;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
TabParent::GetHasLayers(bool* aResult)
{
*aResult = mHasLayers;
return NS_OK;
}
NS_IMETHODIMP
TabParent::PreserveLayers(bool aPreserveLayers)
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -299,16 +299,29 @@
<method name="preserveLayers">
<parameter name="preserve"/>
<body>
// Only useful for remote browsers.
</body>
</method>
+ <property name="renderLayers">
+ <getter>
+ <![CDATA[
+ return this.docShellIsActive;
+ ]]>
+ </getter>
+ <setter>
+ <![CDATA[
+ return this.docShellIsActive = val;
+ ]]>
+ </setter>
+ </property>
+
<property name="hasLayers" readonly="true">
<getter>
<![CDATA[
return this.docShellIsActive;
]]>
</getter>
</property>
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -255,16 +255,37 @@
<body><![CDATA[
let {frameLoader} = this;
if (frameLoader.tabParent) {
frameLoader.tabParent.preserveLayers(preserve);
}
]]></body>
</method>
+ <property name="renderLayers">
+ <getter>
+ <![CDATA[
+ let {frameLoader} = this;
+ if (frameLoader && frameLoader.tabParent) {
+ return frameLoader.tabParent.renderLayers;
+ }
+ return false;
+ ]]>
+ </getter>
+ <setter>
+ <![CDATA[
+ let {frameLoader} = this;
+ if (frameLoader && frameLoader.tabParent) {
+ return frameLoader.tabParent.renderLayers = val;
+ }
+ return false;
+ ]]>
+ </setter>
+ </property>
+
<property name="hasLayers" readonly="true">
<getter><![CDATA[
let {frameLoader} = this;
if (frameLoader.tabParent) {
return frameLoader.tabParent.hasLayers;
}
return false;
]]></getter>