зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1391704 - Avoid flickering while moving tabs across windows, r=mconley.
This commit is contained in:
Родитель
0c9a3b08ee
Коммит
48761699cf
|
@ -1379,6 +1379,25 @@ var gBrowserInit = {
|
|||
|
||||
gRemoteControl.updateVisualCue(Marionette.running);
|
||||
|
||||
// If we are given a tab to swap in, take care of it before first paint to
|
||||
// avoid an about:blank flash.
|
||||
let tabToOpen = window.arguments && window.arguments[0];
|
||||
if (tabToOpen instanceof XULElement) {
|
||||
// Clear the reference to the tab from the arguments array.
|
||||
window.arguments[0] = null;
|
||||
|
||||
// Stop the about:blank load
|
||||
gBrowser.stop();
|
||||
// make sure it has a docshell
|
||||
gBrowser.docShell;
|
||||
|
||||
try {
|
||||
gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToOpen);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait until chrome is painted before executing code not critical to making the window visible
|
||||
this._boundDelayedStartup = this._delayedStartup.bind(this);
|
||||
window.addEventListener("MozAfterPaint", this._boundDelayedStartup);
|
||||
|
@ -1605,6 +1624,8 @@ var gBrowserInit = {
|
|||
return;
|
||||
}
|
||||
|
||||
// We don't check if uriToLoad is a XULElement because this case has
|
||||
// already been handled before first paint, and the argument cleared.
|
||||
if (uriToLoad instanceof Ci.nsIArray) {
|
||||
let count = uriToLoad.length;
|
||||
let specs = [];
|
||||
|
@ -1622,39 +1643,6 @@ var gBrowserInit = {
|
|||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
} catch (e) {}
|
||||
} else if (uriToLoad instanceof XULElement) {
|
||||
// swap the given tab with the default about:blank tab and then close
|
||||
// the original tab in the other window.
|
||||
let tabToOpen = uriToLoad;
|
||||
|
||||
// If this tab was passed as a window argument, clear the
|
||||
// reference to it from the arguments array.
|
||||
if (window.arguments[0] == tabToOpen) {
|
||||
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);
|
||||
}
|
||||
|
||||
try {
|
||||
// Make sure selectedBrowser has the same remote settings as the one
|
||||
// we are swapping in.
|
||||
gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser,
|
||||
tabToOpen.linkedBrowser.isRemoteBrowser,
|
||||
{ remoteType: tabToOpen.linkedBrowser.remoteType });
|
||||
gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToOpen);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
} else if (window.arguments.length >= 3) {
|
||||
// window.arguments[2]: referrer (nsIURI | string)
|
||||
// [3]: postData (nsIInputStream)
|
||||
|
|
|
@ -3009,6 +3009,16 @@
|
|||
|
||||
newTab = true;
|
||||
}
|
||||
aTab._endRemoveArgs = [closeWindow, newTab];
|
||||
|
||||
// swapBrowsersAndCloseOther will take care of closing the window without animation.
|
||||
if (closeWindow && aAdoptedByTab) {
|
||||
// Remove the tab's filter to avoid leaking.
|
||||
if (aTab.linkedPanel) {
|
||||
this._tabFilters.delete(aTab);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aTab._fullyOpen) {
|
||||
// If the opening tab animation hasn't finished before we start closing the
|
||||
|
@ -3079,7 +3089,6 @@
|
|||
tab.owner = null;
|
||||
}
|
||||
|
||||
aTab._endRemoveArgs = [closeWindow, newTab];
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
|
@ -3297,6 +3306,25 @@
|
|||
if (!remoteBrowser._beginRemoveTab(aOtherTab, aOurTab, true))
|
||||
return;
|
||||
|
||||
// If this is the last tab of the window, hide the window
|
||||
// immediately without animation before the docshell swap, to avoid
|
||||
// about:blank being painted.
|
||||
let [closeWindow] = aOtherTab._endRemoveArgs;
|
||||
if (closeWindow) {
|
||||
let win = aOtherTab.ownerGlobal;
|
||||
let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
dwu.suppressAnimation(true);
|
||||
// Only suppressing window animations isn't enough to avoid
|
||||
// an empty content area being painted.
|
||||
let baseWin = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.treeOwner
|
||||
.QueryInterface(Ci.nsIBaseWindow);
|
||||
baseWin.visibility = false;
|
||||
}
|
||||
|
||||
let modifiedAttrs = [];
|
||||
if (aOtherTab.hasAttribute("muted")) {
|
||||
aOurTab.setAttribute("muted", "true");
|
||||
|
@ -3363,7 +3391,11 @@
|
|||
}
|
||||
|
||||
// Finish tearing down the tab that's going away.
|
||||
remoteBrowser._endRemoveTab(aOtherTab);
|
||||
if (closeWindow) {
|
||||
aOtherTab.ownerGlobal.close();
|
||||
} else {
|
||||
remoteBrowser._endRemoveTab(aOtherTab);
|
||||
}
|
||||
|
||||
this.setTabTitle(aOurTab);
|
||||
|
||||
|
@ -3729,6 +3761,14 @@
|
|||
for (var name in aOptions)
|
||||
options += "," + name + "=" + aOptions[name];
|
||||
|
||||
// Play the tab closing animation to give immediate feedback while
|
||||
// waiting for the new window to appear.
|
||||
// content area when the docshells are swapped.
|
||||
if (this.animationsEnabled) {
|
||||
aTab.style.maxWidth = ""; // ensure that fade-out transition happens
|
||||
aTab.removeAttribute("fadein");
|
||||
}
|
||||
|
||||
// tell a new window to take the "dropped" tab
|
||||
return window.openDialog(getBrowserURL(), "_blank", options, aTab);
|
||||
]]>
|
||||
|
@ -3851,7 +3891,8 @@
|
|||
let linkedBrowser = aTab.linkedBrowser;
|
||||
let params = { eventDetail: { adoptedTab: aTab },
|
||||
preferredRemoteType: linkedBrowser.remoteType,
|
||||
sameProcessAsFrameLoader: linkedBrowser.frameLoader };
|
||||
sameProcessAsFrameLoader: linkedBrowser.frameLoader,
|
||||
skipAnimation: true };
|
||||
if (aTab.hasAttribute("usercontextid")) {
|
||||
// new tab must have the same usercontextid as the old one
|
||||
params.userContextId = aTab.getAttribute("usercontextid");
|
||||
|
@ -7407,7 +7448,7 @@
|
|||
window.moveTo(left, top);
|
||||
window.focus();
|
||||
} else {
|
||||
let props = { screenX: left, screenY: top };
|
||||
let props = { screenX: left, screenY: top, suppressanimation: 1 };
|
||||
if (AppConstants.platform != "win") {
|
||||
props.outerWidth = winWidth;
|
||||
props.outerHeight = winHeight;
|
||||
|
|
|
@ -318,15 +318,15 @@ const PanelUI = {
|
|||
*
|
||||
* @return a Promise that resolves once the panel is ready to roll.
|
||||
*/
|
||||
ensureReady() {
|
||||
if (this._readyPromise) {
|
||||
return this._readyPromise;
|
||||
async ensureReady() {
|
||||
if (this._isReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
await window.delayedStartupPromise;
|
||||
this._ensureEventListenersAdded();
|
||||
this.panel.hidden = false;
|
||||
this._readyPromise = Promise.resolve();
|
||||
this._isReady = true;
|
||||
return this._readyPromise;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,8 +26,9 @@ add_task(function* () {
|
|||
// Detach the tab with RDM open.
|
||||
let newWindow = gBrowser.replaceTabWithWindow(tab);
|
||||
|
||||
// Waiting the tab is detached.
|
||||
// Wait until the tab is detached and the new window is fully initialized.
|
||||
yield waitTabIsDetached;
|
||||
yield newWindow.delayedStartupPromise;
|
||||
|
||||
// Get the new tab instance.
|
||||
tab = newWindow.gBrowser.tabs[0];
|
||||
|
|
|
@ -69,7 +69,7 @@ add_task(async function test_swap_frameloader_pagevisibility_events() {
|
|||
|
||||
// We have to wait for the window to load so we can get the selected browser
|
||||
// to listen to.
|
||||
await BrowserTestUtils.waitForEvent(newWindow, "load");
|
||||
await BrowserTestUtils.waitForEvent(newWindow, "DOMContentLoaded");
|
||||
let newWindowBrowser = newWindow.gBrowser.selectedBrowser;
|
||||
|
||||
// Wait for the expected pagehide and pageshow events on the initial browser
|
||||
|
|
Загрузка…
Ссылка в новой задаче