--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -32,16 +32,17 @@ window._gBrowser = {
Services.els.addSystemEventListener(document, "keydown", this, false);
if (AppConstants.platform == "macosx") {
Services.els.addSystemEventListener(document, "keypress", this, false);
}
window.addEventListener("sizemodechange", this);
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";
} else if (Services.prefs.getIntPref("browser.display.document_color_use") == 2) {
this.tabpanels.style.backgroundColor =
Services.prefs.getCharPref("browser.display.background_color");
}
@@ -318,16 +319,39 @@ window._gBrowser = {
let filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
.createInstance(Ci.nsIWebProgress);
filter.addProgressListener(tabListener, Ci.nsIWebProgress.NOTIFY_ALL);
this._tabListeners.set(tab, tabListener);
this._tabFilters.set(tab, filter);
browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
},
+ _preopenPinnedTabs() {
+ let numPinnedTabs = 0;
+ let windows = browserWindows();
+ windows.next();
+ let isOnlyWindow = windows.next().done;
+ if (isOnlyWindow) {
+ numPinnedTabs = Services.prefs.getIntPref("browser.tabs.firstWindowRestore.numPinnedTabs", 0);
+ }
+
+ for (let i = 0; i < numPinnedTabs; i++) {
+ let tab = this.addTab("about:blank", {
+ skipAnimation: true,
+ noInitialLabel: true,
+ skipBackgroundNotify: true,
+ createLazyBrowser: true,
+ pinned: true,
+ isForFirstWindowRestore: true,
+ });
+
+ tab.setAttribute("busy", "true");
+ }
+ },
+
/**
* BEGIN FORWARDED BROWSER PROPERTIES. IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT
* MAKE SURE TO ADD IT HERE AS WELL.
*/
get canGoBack() {
return this.selectedBrowser.canGoBack;
},
@@ -535,46 +559,63 @@ window._gBrowser = {
},
_updateTabBarForPinnedTabs() {
this.tabContainer._unlockTabSizing();
this.tabContainer._positionPinnedTabs();
this.tabContainer._updateCloseButtons();
},
- _notifyPinnedStatus(aTab) {
- this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: aTab.pinned });
+ _notifyPinnedStatus(aTab, aDeferContentMessage = false) {
+ if (!aDeferContentMessage) {
+ this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: aTab.pinned });
+ }
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) {
+ delete aTab._preopened;
+ this._insertBrowser(aTab);
+ this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: aTab.pinned });
+ },
+
pinTab(aTab) {
if (aTab.pinned)
return;
if (aTab.hidden)
this.showTab(aTab);
this.moveTabTo(aTab, this._numPinnedTabs);
aTab.setAttribute("pinned", "true");
this._updateTabBarForPinnedTabs();
this._notifyPinnedStatus(aTab);
+ this._maybeUpdateNumPinnedTabsPref();
},
unpinTab(aTab) {
if (!aTab.pinned)
return;
this.moveTabTo(aTab, this._numPinnedTabs - 1);
aTab.removeAttribute("pinned");
aTab.style.marginInlineStart = "";
this._updateTabBarForPinnedTabs();
this._notifyPinnedStatus(aTab);
+ this._maybeUpdateNumPinnedTabsPref();
},
previewTab(aTab, aCallback) {
let currentTab = this.selectedTab;
try {
// Suppress focus, ownership and selected tab changes
this._previewMode = true;
this.selectedTab = aTab;
@@ -2164,16 +2205,17 @@ window._gBrowser = {
postData,
preferredRemoteType,
referrerPolicy,
referrerURI,
relatedToCurrent,
sameProcessAsFrameLoader,
skipAnimation,
skipBackgroundNotify,
+ isForFirstWindowRestore,
triggeringPrincipal,
userContextId,
recordExecution,
replayExecution,
} = {}) {
// if we're adding tabs, we're past interrupt mode, ditch the owner
if (this.selectedTab.owner) {
this.selectedTab.owner = null;
@@ -2317,16 +2359,19 @@ window._gBrowser = {
if (tabAfter) {
this._updateTabsAfterInsert();
} else {
t._tPos = index;
}
if (pinned) {
this._updateTabBarForPinnedTabs();
+ if (!isForFirstWindowRestore) {
+ this._maybeUpdateNumPinnedTabsPref();
+ }
}
this.tabContainer._setPositionalAttributes();
TabBarVisibility.update();
// If we don't have a preferred remote type, and we have a remote
// opener, use the opener's remote type.
if (!preferredRemoteType && openerBrowser) {
@@ -2484,17 +2529,17 @@ window._gBrowser = {
requestAnimationFrame(function() {
// kick the animation off
t.setAttribute("fadein", "true");
});
}
// Additionally send pinned tab events
if (pinned) {
- this._notifyPinnedStatus(t);
+ this._notifyPinnedStatus(t, isForFirstWindowRestore);
}
return t;
},
warnAboutClosingTabs(tabsToClose, aCloseTabs, aOptionalMessage) {
if (tabsToClose <= 1)
return true;
@@ -2923,18 +2968,20 @@ window._gBrowser = {
if (aTab.hidden)
this.tabContainer._updateHiddenTabsStatus();
// ... and fix up the _tPos properties immediately.
for (let i = aTab._tPos; i < this.tabs.length; i++)
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();
setTimeout(function(tabs) {
tabs._lastTabClosedByMouse = false;
}, 0, this.tabContainer);
}
--- a/browser/modules/BrowserWindowTracker.jsm
+++ b/browser/modules/BrowserWindowTracker.jsm
@@ -87,16 +87,21 @@ function _trackWindowOrder(window) {
}
function _untrackWindowOrder(window) {
let idx = _trackedWindows.indexOf(window);
if (idx >= 0)
_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) {
// Add event listeners
TAB_EVENTS.forEach(function(event) {
window.gBrowser.tabContainer.addEventListener(event, _handleEvent);
});
WINDOW_EVENTS.forEach(function(event) {
@@ -129,16 +134,17 @@ var WindowHelper = {
onActivate(window, hasFocus) {
// If this window was the last focused window, we don't need to do anything
if (window == _trackedWindows[0])
return;
_untrackWindowOrder(window);
_trackWindowOrder(window);
+ _trackPinnedTabs(window);
_updateCurrentContentOuterWindowID(window.gBrowser.selectedBrowser);
},
onSizemodeChange(window) {
if (window.windowState == window.STATE_MINIMIZED) {
// Make sure to have the minimized window at the end of the list.
_untrackWindowOrder(window);