Bug 603903 - Part 2: restore session when restarted by Windows
MozReview-Commit-ID: EEKZAZZ9E98
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -851,16 +851,17 @@ pref("browser.rights.3.shown", false);
#ifdef DEBUG
// Don't show the about:rights notification in debug builds.
pref("browser.rights.override", true);
#endif
pref("browser.sessionstore.resume_from_crash", true);
pref("browser.sessionstore.resume_session_once", false);
+pref("browser.sessionstore.resuming_after_os_restart", false);
// Minimal interval between two save operations in milliseconds (while the user is active).
pref("browser.sessionstore.interval", 15000); // 15 seconds
// Minimal interval between two save operations in milliseconds (while the user is idle).
pref("browser.sessionstore.interval.idle", 3600000); // 1h
// Time (ms) before we assume that the user is idle and that we don't need to
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1319,17 +1319,17 @@ BrowserGlue.prototype = {
// - The quit dialog will be shown
// 2. aQuitType == "lastwindow" && browser.tabs.warnOnClose == true
// - The "closing multiple tabs" dialog will be shown
//
// aQuitType == "lastwindow" is overloaded. "lastwindow" is used to indicate
// "the last window is closing but we're not quitting (a non-browser window is open)"
// and also "we're quitting by closing the last window".
- if (aQuitType == "restart")
+ if (aQuitType == "restart" || aQuitType == "os-restart")
return;
var windowcount = 0;
var pagecount = 0;
var browserEnum = Services.wm.getEnumerator("navigator:browser");
let allWindowsPrivate = true;
while (browserEnum.hasMoreElements()) {
// XXXbz should we skip closed windows here?
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -1722,18 +1722,22 @@ var SessionStoreInternal = {
},
/**
* On quitting application
* @param aData
* String type of quitting
*/
onQuitApplication: function ssi_onQuitApplication(aData) {
- if (aData == "restart") {
+ if (aData == "restart" || aData == "os-restart") {
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
+ if (aData == "os-restart" &&
+ !this._prefBranch.getBoolPref("sessionstore.resume_session_once")) {
+ this._prefBranch.setBoolPref("sessionstore.resuming_after_os_restart", true);
+ }
this._prefBranch.setBoolPref("sessionstore.resume_session_once", true);
}
// The browser:purge-session-history notification fires after the
// quit-application notification so unregister the
// browser:purge-session-history notification to prevent clearing
// session data on disk on a restart. It is also unnecessary to
// perform any other sanitization processing on a restart as the
--- a/browser/components/sessionstore/nsSessionStartup.js
+++ b/browser/components/sessionstore/nsSessionStartup.js
@@ -97,16 +97,27 @@ SessionStartup.prototype = {
// do not need to initialize anything in auto-started private browsing sessions
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
this._initialized = true;
gOnceInitializedDeferred.resolve();
return;
}
+ if (Services.prefs.getBoolPref("browser.sessionstore.resuming_after_os_restart")) {
+ if (!Services.appinfo.restartedByOS) {
+ // We had set resume_session_once in order to resume after an OS restart,
+ // but we aren't automatically started by the OS (or else appinfo.restartedByOS
+ // would have been set). Therefore we should clear resume_session_once
+ // to avoid forcing a resume for a normal startup.
+ Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", false);
+ }
+ Services.prefs.setBoolPref("browser.sessionstore.resuming_after_os_restart", false);
+ }
+
this._resumeSessionEnabled =
Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") ||
Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION;
SessionFile.read().then(
this._onSessionFileRead.bind(this),
console.error
);
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -65,16 +65,17 @@
#include "mozilla/MouseEvents.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/ipc/MessageChannel.h"
#include <algorithm>
#include <limits>
#include "nsWindow.h"
+#include "nsAppRunner.h"
#include <shellapi.h>
#include <windows.h>
#include <wtsapi32.h>
#include <process.h>
#include <commctrl.h>
#include <unknwn.h>
#include <psapi.h>
@@ -5025,16 +5026,30 @@ LRESULT CALLBACK nsWindow::WindowProcInt
}
LRESULT res = ::CallWindowProcW(targetWindow->GetPrevWindowProc(),
hWnd, msg, wParam, lParam);
return res;
}
+const char16_t*
+GetQuitType()
+{
+ if (Preferences::GetBool(PREF_WIN_REGISTER_APPLICATION_RESTART, false)) {
+ DWORD cchCmdLine = 0;
+ HRESULT rc =
+ ::GetApplicationRestartSettings(::GetCurrentProcess(), nullptr, &cchCmdLine, nullptr);
+ if (rc == S_OK) {
+ return u"os-restart";
+ }
+ }
+ return nullptr;
+}
+
// The main windows message processing method for plugins.
// The result means whether this method processed the native
// event for plugin. If false, the native event should be
// processed by the caller self.
bool
nsWindow::ProcessMessageForPlugin(const MSG &aMsg,
MSGResult& aResult)
{
@@ -5197,17 +5212,19 @@ nsWindow::ProcessMessage(UINT msg, WPARA
{
// Ask if it's ok to quit, and store the answer until we
// get WM_ENDSESSION signaling the round is complete.
nsCOMPtr<nsIObserverService> obsServ =
mozilla::services::GetObserverService();
nsCOMPtr<nsISupportsPRBool> cancelQuit =
do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
cancelQuit->SetData(false);
- obsServ->NotifyObservers(cancelQuit, "quit-application-requested", nullptr);
+
+ const char16_t* quitType = GetQuitType();
+ obsServ->NotifyObservers(cancelQuit, "quit-application-requested", quitType);
bool abortQuit;
cancelQuit->GetData(&abortQuit);
sCanQuit = abortQuit ? TRI_FALSE : TRI_TRUE;
}
*aRetValue = sCanQuit ? TRUE : FALSE;
result = true;
break;
@@ -5228,19 +5245,21 @@ nsWindow::ProcessMessage(UINT msg, WPARA
// Let's fake a shutdown sequence without actually closing windows etc.
// to avoid Windows killing us in the middle. A proper shutdown would
// require having a chance to pump some messages. Unfortunately
// Windows won't let us do that. Bug 212316.
nsCOMPtr<nsIObserverService> obsServ =
mozilla::services::GetObserverService();
const char16_t* context = u"shutdown-persist";
const char16_t* syncShutdown = u"syncShutdown";
+ const char16_t* quitType = GetQuitType();
+
obsServ->NotifyObservers(nullptr, "quit-application-granted", syncShutdown);
obsServ->NotifyObservers(nullptr, "quit-application-forced", nullptr);
- obsServ->NotifyObservers(nullptr, "quit-application", nullptr);
+ obsServ->NotifyObservers(nullptr, "quit-application", quitType);
obsServ->NotifyObservers(nullptr, "profile-change-net-teardown", context);
obsServ->NotifyObservers(nullptr, "profile-change-teardown", context);
obsServ->NotifyObservers(nullptr, "profile-before-change", context);
obsServ->NotifyObservers(nullptr, "profile-before-change-qm", context);
obsServ->NotifyObservers(nullptr, "profile-before-change-telemetry", context);
ExitThisProcessSafely();
}
sCanQuit = TRI_UNKNOWN;