From 66795dc4917b1f24110d9da118000644f53e54e5 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Tue, 22 Oct 2013 08:20:15 +0200 Subject: [PATCH] Bug 928335 - Disable 'Restore Last Session' menuitem after restoring the last session; r=dao --- browser/base/content/browser.js | 24 ++++++- .../sessionstore/src/SessionStore.jsm | 69 ++++++++++++------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index f26fd5c7463f..06bd8ce45065 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1215,9 +1215,7 @@ var gBrowserInit = { SessionStore.promiseInitialized.then(() => { // Enable the Restore Last Session command if needed - if (SessionStore.canRestoreLastSession && - !PrivateBrowsingUtils.isWindowPrivate(window)) - goSetCommandEnabled("Browser:RestoreLastSession", true); + RestoreLastSessionObserver.init(); TabView.init(); @@ -7001,6 +6999,26 @@ function switchToTabHavingURI(aURI, aOpenNew) { return false; } +let RestoreLastSessionObserver = { + init: function () { + if (SessionStore.canRestoreLastSession && + !PrivateBrowsingUtils.isWindowPrivate(window)) { + Services.obs.addObserver(this, "sessionstore-last-session-cleared", true); + goSetCommandEnabled("Browser:RestoreLastSession", true); + } + }, + + observe: function () { + // The last session can only be restored once so there's + // no way we need to re-enable our menu item. + Services.obs.removeObserver(this, "sessionstore-last-session-cleared"); + goSetCommandEnabled("Browser:RestoreLastSession", false); + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsISupportsWeakReference]) +}; + function restoreLastSession() { SessionStore.restoreLastSession(); } diff --git a/browser/components/sessionstore/src/SessionStore.jsm b/browser/components/sessionstore/src/SessionStore.jsm index e34229cae867..3cb72cd54ac0 100644 --- a/browser/components/sessionstore/src/SessionStore.jsm +++ b/browser/components/sessionstore/src/SessionStore.jsm @@ -23,6 +23,7 @@ const TAB_STATE_RESTORING = 2; const NOTIFY_WINDOWS_RESTORED = "sessionstore-windows-restored"; const NOTIFY_BROWSER_STATE_RESTORED = "sessionstore-browser-state-restored"; +const NOTIFY_LAST_SESSION_CLEARED = "sessionstore-last-session-cleared"; // Maximum number of tabs to restore simultaneously. Previously controlled by // the browser.sessionstore.max_concurrent_tabs pref. @@ -329,12 +330,6 @@ let SessionStoreInternal = { // number of tabs currently restoring _tabsRestoringCount: 0, - // The state from the previous session (after restoring pinned tabs). This - // state is persisted and passed through to the next session during an app - // restart to make the third party add-on warning not trash the deferred - // session - _lastSessionState: null, - // When starting Firefox with a single private window, this is the place // where we keep the session we actually wanted to restore in case the user // decides to later open a non-private window as well. @@ -361,16 +356,15 @@ let SessionStoreInternal = { return this._deferredInitialized.promise; }, - /* ........ Public Getters .............. */ get canRestoreLastSession() { - return !!this._lastSessionState; + return LastSession.canRestore; }, set canRestoreLastSession(val) { // Cheat a bit; only allow false. - if (val) - return; - this._lastSessionState = null; + if (!val) { + LastSession.clear(); + } }, /** @@ -419,13 +413,15 @@ let SessionStoreInternal = { state = iniState; else state = null; - if (remainingState.windows.length) - this._lastSessionState = remainingState; + + if (remainingState.windows.length) { + LastSession.setState(remainingState); + } } else { // Get the last deferred session in case the user still wants to // restore it - this._lastSessionState = state.lastSessionState; + LastSession.setState(state.lastSessionState); let lastSessionCrashed = state.session && state.session.state && @@ -1062,7 +1058,7 @@ let SessionStoreInternal = { if (aData != "restart") { // Throw away the previous session on shutdown - this._lastSessionState = null; + LastSession.clear(); } this._loadState = STATE_QUITTING; // just to be sure @@ -1079,7 +1075,7 @@ let SessionStoreInternal = { // quit-application notification so the browser is about to exit. if (this._loadState == STATE_QUITTING) return; - this._lastSessionState = null; + LastSession.clear(); let openWindows = {}; this._forEachBrowserWindow(function(aWindow) { Array.forEach(aWindow.gBrowser.tabs, function(aTab) { @@ -1765,7 +1761,7 @@ let SessionStoreInternal = { }, /** - * Restores the session state stored in _lastSessionState. This will attempt + * Restores the session state stored in LastSession. This will attempt * to merge data into the current session. If a window was opened at startup * with pinned tab(s), then the remaining data from the previous session for * that window will be opened into that winddow. Otherwise new windows will @@ -1783,7 +1779,7 @@ let SessionStoreInternal = { windows[aWindow.__SS_lastSessionWindowID] = aWindow; }); - let lastSessionState = this._lastSessionState; + let lastSessionState = LastSession.getState(); // This shouldn't ever be the case... if (!lastSessionState.windows.length) @@ -1862,7 +1858,7 @@ let SessionStoreInternal = { // Update the session start time using the restored session state. this._updateSessionStartTime(lastSessionState); - this._lastSessionState = null; + LastSession.clear(); }, /** @@ -2123,8 +2119,8 @@ let SessionStoreInternal = { }; // Persist the last session if we deferred restoring it - if (this._lastSessionState) { - state.lastSessionState = this._lastSessionState; + if (LastSession.canRestore) { + state.lastSessionState = LastSession.getState(); } // If we were called by the SessionSaver and started with only a private @@ -3522,8 +3518,8 @@ let SessionStoreInternal = { * from state. It will contain the cookies that go along with the history * entries in those tabs. It will also contain window position information. * - * defaultState will be restored at startup. state will be placed into - * this._lastSessionState and will be kept in case the user explicitly wants + * defaultState will be restored at startup. state will be passed into + * LastSession and will be kept in case the user explicitly wants * to restore the previous session (publicly exposed as restoreLastSession). * * @param state @@ -4533,3 +4529,30 @@ let TabState = { return true; }, }; + +// The state from the previous session (after restoring pinned tabs). This +// state is persisted and passed through to the next session during an app +// restart to make the third party add-on warning not trash the deferred +// session +let LastSession = { + _state: null, + + get canRestore() { + return !!this._state; + }, + + getState: function () { + return this._state; + }, + + setState: function (state) { + this._state = state; + }, + + clear: function () { + if (this._state) { + this._state = null; + Services.obs.notifyObservers(null, NOTIFY_LAST_SESSION_CLEARED, null); + } + } +};