зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1442694 - Preopen pinned tabs before session restore r=Gijs
When we open firefox with pinned tabs, we first paint a window with one tab open, and then that tab gets displaced after the pinned tabs come in. This aims to ensure that our first paint contains the pinned tab, so that we don't have tabs moving around after first paint. MozReview-Commit-ID: GC1y6NlgLTd Differential Revision: https://phabricator.services.mozilla.com/D18742 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
0e903787da
Коммит
978e0344ff
|
@ -22,6 +22,11 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.tab-icon-pending[preopened],
|
||||
.tab-icon-image[preopened] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tab-sharing-icon-overlay[sharing]:not([selected]),
|
||||
.tab-icon-overlay[soundplaying][pinned],
|
||||
.tab-icon-overlay[muted][pinned],
|
||||
|
|
|
@ -32,6 +32,7 @@ window._gBrowser = {
|
|||
window.addEventListener("occlusionstatechange", this);
|
||||
|
||||
this._setupInitialBrowserAndTab();
|
||||
this._preopenPinnedTabs();
|
||||
|
||||
if (Services.prefs.getBoolPref("browser.display.use_system_colors")) {
|
||||
this.tabpanels.style.backgroundColor = "-moz-default-background-color";
|
||||
|
@ -383,6 +384,29 @@ window._gBrowser = {
|
|||
browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
},
|
||||
|
||||
_preopenPinnedTabs() {
|
||||
let numPinnedTabs = 0;
|
||||
let windows = browserWindows();
|
||||
windows.getNext();
|
||||
let isOnlyWindow = !windows.hasMoreElements();
|
||||
if (isOnlyWindow) {
|
||||
numPinnedTabs = Services.prefs.getIntPref("browser.tabs.firstWindowRestore.numPinnedTabs", 0);
|
||||
}
|
||||
|
||||
for (let i = 0; i < numPinnedTabs; i++) {
|
||||
let tab = this.addTrustedTab("about:blank", {
|
||||
skipAnimation: true,
|
||||
noInitialLabel: true,
|
||||
skipBackgroundNotify: true,
|
||||
createLazyBrowser: true,
|
||||
pinned: true,
|
||||
isForFirstWindowRestore: true,
|
||||
});
|
||||
|
||||
tab.setAttribute("preopened", "true");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* BEGIN FORWARDED BROWSER PROPERTIES. IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT
|
||||
* MAKE SURE TO ADD IT HERE AS WELL.
|
||||
|
@ -593,14 +617,32 @@ window._gBrowser = {
|
|||
this.tabContainer._updateCloseButtons();
|
||||
},
|
||||
|
||||
_notifyPinnedStatus(aTab) {
|
||||
_sendPinnedTabContentMessage(aTab) {
|
||||
this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: aTab.pinned });
|
||||
},
|
||||
|
||||
_notifyPinnedStatus(aTab, aDeferContentMessage = false) {
|
||||
if (!aDeferContentMessage) {
|
||||
this._sendPinnedTabContentMessage(aTab);
|
||||
}
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent(aTab.pinned ? "TabPinned" : "TabUnpinned", true, false);
|
||||
aTab.dispatchEvent(event);
|
||||
},
|
||||
|
||||
_maybeUpdateNumPinnedTabsPref() {
|
||||
if (BrowserWindowTracker.getTopWindow() == window) {
|
||||
Services.prefs.setIntPref("browser.tabs.firstWindowRestore.numPinnedTabs",
|
||||
this._numPinnedTabs);
|
||||
}
|
||||
},
|
||||
|
||||
activatePreopenedPinnedTab(aTab) {
|
||||
this._insertBrowser(aTab);
|
||||
this._sendPinnedTabContentMessage(aTab);
|
||||
},
|
||||
|
||||
pinTab(aTab) {
|
||||
if (aTab.pinned)
|
||||
return;
|
||||
|
@ -612,6 +654,7 @@ window._gBrowser = {
|
|||
aTab.setAttribute("pinned", "true");
|
||||
this._updateTabBarForPinnedTabs();
|
||||
this._notifyPinnedStatus(aTab);
|
||||
this._maybeUpdateNumPinnedTabsPref();
|
||||
},
|
||||
|
||||
unpinTab(aTab) {
|
||||
|
@ -623,6 +666,7 @@ window._gBrowser = {
|
|||
aTab.style.marginInlineStart = "";
|
||||
this._updateTabBarForPinnedTabs();
|
||||
this._notifyPinnedStatus(aTab);
|
||||
this._maybeUpdateNumPinnedTabsPref();
|
||||
},
|
||||
|
||||
previewTab(aTab, aCallback) {
|
||||
|
@ -2296,6 +2340,7 @@ window._gBrowser = {
|
|||
forceNotRemote,
|
||||
fromExternal,
|
||||
index,
|
||||
isForFirstWindowRestore,
|
||||
lazyTabTitle,
|
||||
name,
|
||||
nextTabParentId,
|
||||
|
@ -2479,6 +2524,9 @@ window._gBrowser = {
|
|||
|
||||
if (pinned) {
|
||||
this._updateTabBarForPinnedTabs();
|
||||
if (!isForFirstWindowRestore) {
|
||||
this._maybeUpdateNumPinnedTabsPref();
|
||||
}
|
||||
}
|
||||
this.tabContainer._setPositionalAttributes();
|
||||
|
||||
|
@ -2558,13 +2606,15 @@ window._gBrowser = {
|
|||
userContextId);
|
||||
b.registeredOpenURI = lazyBrowserURI;
|
||||
}
|
||||
SessionStore.setTabState(t, {
|
||||
entries: [{
|
||||
url: lazyBrowserURI ? lazyBrowserURI.spec : "about:blank",
|
||||
title: lazyTabTitle,
|
||||
triggeringPrincipal_base64: E10SUtils.serializePrincipal(triggeringPrincipal),
|
||||
}],
|
||||
});
|
||||
if (!isForFirstWindowRestore) {
|
||||
SessionStore.setTabState(t, {
|
||||
entries: [{
|
||||
url: lazyBrowserURI ? lazyBrowserURI.spec : "about:blank",
|
||||
title: lazyTabTitle,
|
||||
triggeringPrincipal_base64: E10SUtils.serializePrincipal(triggeringPrincipal),
|
||||
}],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this._insertBrowser(t, true);
|
||||
}
|
||||
|
@ -2602,7 +2652,9 @@ window._gBrowser = {
|
|||
|
||||
// If we didn't swap docShells with a preloaded browser
|
||||
// then let's just continue loading the page normally.
|
||||
if (!usingPreloadedContent && (!uriIsAboutBlank || !allowInheritPrincipal)) {
|
||||
if (!usingPreloadedContent &&
|
||||
!createLazyBrowser &&
|
||||
(!uriIsAboutBlank || !allowInheritPrincipal)) {
|
||||
// pretend the user typed this so it'll be available till
|
||||
// the document successfully loads
|
||||
if (aURI && !gInitialPages.includes(aURI)) {
|
||||
|
@ -2655,7 +2707,7 @@ window._gBrowser = {
|
|||
|
||||
// Additionally send pinned tab events
|
||||
if (pinned) {
|
||||
this._notifyPinnedStatus(t);
|
||||
this._notifyPinnedStatus(t, isForFirstWindowRestore);
|
||||
}
|
||||
|
||||
return t;
|
||||
|
@ -3153,8 +3205,10 @@ window._gBrowser = {
|
|||
this.tabs[i]._tPos = i;
|
||||
|
||||
if (!this._windowIsClosing) {
|
||||
if (wasPinned)
|
||||
if (wasPinned) {
|
||||
this.tabContainer._positionPinnedTabs();
|
||||
this._maybeUpdateNumPinnedTabsPref();
|
||||
}
|
||||
|
||||
// update tab close buttons state
|
||||
this.tabContainer._updateCloseButtons();
|
||||
|
@ -3839,7 +3893,6 @@ window._gBrowser = {
|
|||
skipAnimation: true,
|
||||
index: aIndex,
|
||||
createLazyBrowser,
|
||||
allowInheritPrincipal: createLazyBrowser,
|
||||
};
|
||||
|
||||
let numPinned = this._numPinnedTabs;
|
||||
|
@ -5016,6 +5069,7 @@ class TabProgressListener {
|
|||
this.mTab.removeAttribute("crashed");
|
||||
}
|
||||
|
||||
this.mTab.removeAttribute("preopened");
|
||||
if (this._shouldShowProgress(aRequest)) {
|
||||
if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_RESTORING) &&
|
||||
aWebProgress && aWebProgress.isTopLevel) {
|
||||
|
|
|
@ -1937,10 +1937,10 @@
|
|||
anonid="tab-throbber"
|
||||
class="tab-throbber"
|
||||
layer="true"/>
|
||||
<xul:hbox xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected,pendingicon"
|
||||
<xul:hbox xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected,pendingicon,preopened"
|
||||
anonid="tab-icon-pending"
|
||||
class="tab-icon-pending"/>
|
||||
<xul:image xbl:inherits="src=image,triggeringprincipal=iconloadingprincipal,requestcontextid,fadein,pinned,selected=visuallyselected,busy,crashed,sharing"
|
||||
<xul:image xbl:inherits="src=image,triggeringprincipal=iconloadingprincipal,requestcontextid,fadein,pinned,selected=visuallyselected,busy,crashed,sharing,preopened"
|
||||
anonid="tab-icon-image"
|
||||
class="tab-icon-image"
|
||||
validate="never"
|
||||
|
|
|
@ -731,6 +731,7 @@ var SessionStoreInternal = {
|
|||
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
|
||||
|
||||
this._restore_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
|
||||
this._restore_pinned_tabs_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_pinned_tabs_on_demand");
|
||||
this._prefBranch.addObserver("sessionstore.restore_on_demand", this, true);
|
||||
|
||||
gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting");
|
||||
|
@ -3203,6 +3204,7 @@ var SessionStoreInternal = {
|
|||
if (!uriObj || (uriObj && !window.gBrowser.isLocalAboutURI(uriObj))) {
|
||||
tab.setAttribute("busy", "true");
|
||||
}
|
||||
tab.removeAttribute("preopened");
|
||||
|
||||
// Hack to ensure that the about:home, about:newtab, and about:welcome
|
||||
// favicon is loaded instantaneously, to avoid flickering and improve
|
||||
|
@ -3650,7 +3652,7 @@ var SessionStoreInternal = {
|
|||
|
||||
// We need to keep track of the initially open tabs so that they
|
||||
// can be moved to the end of the restored tabs.
|
||||
let initialTabs;
|
||||
let initialTabs = [];
|
||||
if (!overwriteTabs && firstWindow) {
|
||||
initialTabs = Array.slice(tabbrowser.tabs);
|
||||
}
|
||||
|
@ -3658,8 +3660,11 @@ var SessionStoreInternal = {
|
|||
// Get rid of tabs that aren't needed anymore.
|
||||
if (overwriteTabs) {
|
||||
for (let i = tabbrowser.browsers.length - 1; i >= 0; i--) {
|
||||
if (!tabbrowser.tabs[i].selected) {
|
||||
if (!tabbrowser.tabs[i].selected &&
|
||||
!tabbrowser.tabs[i].hasAttribute("preopened")) {
|
||||
tabbrowser.removeTab(tabbrowser.tabs[i]);
|
||||
} else if (tabbrowser.tabs[i].hasAttribute("preopened")) {
|
||||
initialTabs.push(tabbrowser.tabs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3678,13 +3683,24 @@ var SessionStoreInternal = {
|
|||
if (select &&
|
||||
tabbrowser.selectedTab.userContextId == userContextId) {
|
||||
tab = tabbrowser.selectedTab;
|
||||
if (!tabData.pinned) {
|
||||
if (tab.pinned && !tabData.pinned) {
|
||||
tabbrowser.unpinTab(tab);
|
||||
} else if (!tab.pinned && tabData.pinned) {
|
||||
tabbrowser.removeTab(tabbrowser.tabs[t]);
|
||||
tabbrowser.pinTab(tab);
|
||||
tabbrowser.moveTabTo(tab, t);
|
||||
}
|
||||
|
||||
tabbrowser.moveTabToEnd();
|
||||
if (aWindow.gMultiProcessBrowser && !tab.linkedBrowser.isRemoteBrowser) {
|
||||
tabbrowser.updateBrowserRemoteness(tab.linkedBrowser, true);
|
||||
}
|
||||
} else if (tabData.pinned &&
|
||||
tabbrowser.tabs[t] &&
|
||||
tabbrowser.tabs[t].pinned &&
|
||||
!tabbrowser.tabs[t].linkedPanel) {
|
||||
tab = tabbrowser.tabs[t];
|
||||
tabbrowser.activatePreopenedPinnedTab(tab);
|
||||
}
|
||||
|
||||
// Add a new tab if needed.
|
||||
|
@ -3733,11 +3749,14 @@ var SessionStoreInternal = {
|
|||
}
|
||||
|
||||
// Move the originally open tabs to the end.
|
||||
if (initialTabs) {
|
||||
let endPosition = tabbrowser.tabs.length - 1;
|
||||
for (let i = 0; i < initialTabs.length; i++) {
|
||||
tabbrowser.unpinTab(initialTabs[i]);
|
||||
tabbrowser.moveTabTo(initialTabs[i], endPosition);
|
||||
let endPosition = tabbrowser.tabs.length - 1;
|
||||
for (let tab of initialTabs) {
|
||||
if (tab.hasAttribute("preopened") &&
|
||||
!tab.linkedPanel) {
|
||||
tabbrowser.removeTab(tab);
|
||||
} else if (!tab.hasAttribute("preopened")) {
|
||||
tabbrowser.unpinTab(tab);
|
||||
tabbrowser.moveTabTo(tab, endPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3998,6 +4017,9 @@ var SessionStoreInternal = {
|
|||
for (let t = 0; t < aTabs.length; t++) {
|
||||
if (t != selectedIndex) {
|
||||
this.restoreTab(aTabs[t], aTabData[t]);
|
||||
if (this._restore_pinned_tabs_on_demand) {
|
||||
aTabs[t].removeAttribute("preopened");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -96,6 +96,11 @@ function _untrackWindowOrder(window) {
|
|||
_trackedWindows.splice(idx, 1);
|
||||
}
|
||||
|
||||
function _trackPinnedTabs(window) {
|
||||
Services.prefs.setIntPref("browser.tabs.firstWindowRestore.numPinnedTabs",
|
||||
window.gBrowser._numPinnedTabs);
|
||||
}
|
||||
|
||||
// Methods that impact a window. Put into single object for organization.
|
||||
var WindowHelper = {
|
||||
addWindow(window) {
|
||||
|
@ -138,6 +143,7 @@ var WindowHelper = {
|
|||
|
||||
_untrackWindowOrder(window);
|
||||
_trackWindowOrder(window);
|
||||
_trackPinnedTabs(window);
|
||||
|
||||
_updateCurrentContentOuterWindowID(window.gBrowser.selectedBrowser);
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче