diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp index 0e5d530b33a..1bb81ef8cfe 100644 --- a/browser/app/nsBrowserApp.cpp +++ b/browser/app/nsBrowserApp.cpp @@ -191,6 +191,10 @@ static int do_main(int argc, char* argv[], nsIFile *xreDirectory) argv[1] = argv[0]; argv++; argc--; + } else if (IsArg(argv[1], "BackgroundSessionClosed")) { + // This command line flag is used for indirect shutdowns, the OS + // relaunches Metro Firefox with this command line arg. + mainFlags = XRE_MAIN_FLAG_USE_METRO; } else { // This command-line flag is used to test the metro browser in a desktop // environment. diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index a71265f2bdf..8ea8ac12081 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -4028,7 +4028,7 @@ static XREMain* xreMainPtr; // must be called by the thread we want as the main thread nsresult -XRE_metroStartup() +XRE_metroStartup(bool runXREMain) { nsresult rv; @@ -4044,8 +4044,10 @@ XRE_metroStartup() rv = xreMainPtr->mScopedXPCom->Initialize(); NS_ENSURE_SUCCESS(rv, rv); - rv = xreMainPtr->XRE_mainRun(); - NS_ENSURE_SUCCESS(rv, rv); + if (runXREMain) { + rv = xreMainPtr->XRE_mainRun(); + NS_ENSURE_SUCCESS(rv, rv); + } return NS_OK; } diff --git a/widget/windows/winrt/MetroApp.cpp b/widget/windows/winrt/MetroApp.cpp index 72a3068df44..22f293dfd60 100644 --- a/widget/windows/winrt/MetroApp.cpp +++ b/widget/windows/winrt/MetroApp.cpp @@ -11,6 +11,8 @@ #include "MetroAppShell.h" #include "nsICommandLineRunner.h" #include "FrameworkView.h" +#include "nsAppDirectoryServiceDefs.h" +#include using namespace ABI::Windows::ApplicationModel; using namespace ABI::Windows::ApplicationModel::Core; @@ -22,7 +24,7 @@ using namespace Microsoft::WRL::Wrappers; // Metro specific XRE methods we call from here on an // appropriate thread. -extern nsresult XRE_metroStartup(); +extern nsresult XRE_metroStartup(bool runXREMain); extern void XRE_metroShutdown(); #ifdef PR_LOGGING @@ -68,7 +70,7 @@ MetroApp::Initialize() if (!xpcomInit) { xpcomInit = true; Log(L"XPCOM startup initialization began"); - nsresult rv = XRE_metroStartup(); + nsresult rv = XRE_metroStartup(true); Log(L"XPCOM startup initialization complete"); if (NS_FAILED(rv)) { Log(L"XPCOM startup initialization failed, bailing. rv=%X", rv); @@ -195,6 +197,17 @@ MetroApp::PostSleepWakeNotification(const bool aIsSleep) } } } + +static bool +IsBackgroundSessionClosedStartup() +{ + int argc; + LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); + bool backgroundSessionClosed = argc > 1 && !wcsicmp(argv[1], L"-BackgroundSessionClosed"); + LocalFree(argv); + return backgroundSessionClosed; +} + bool XRE_MetroCoreApplicationRun() { @@ -219,7 +232,28 @@ XRE_MetroCoreApplicationRun() } sFrameworkView = Make(sMetroApp.Get()); - sCoreApp->Run(sMetroApp.Get()); + + // Perform any cleanup for unclean shutdowns here, such as when the background session + // is closed via the appbar on the left when outside of Metro. Windows restarts the + // process solely for cleanup reasons. + if (IsBackgroundSessionClosedStartup() && SUCCEEDED(XRE_metroStartup(false))) { + + // Whether or not to use sessionstore depends on if the bak exists. Since host process + // shutdown isn't a crash we shouldn't restore sessionstore. + nsCOMPtr sessionBAK; + if (NS_FAILED(NS_GetSpecialDirectory("ProfDS", getter_AddRefs(sessionBAK)))) { + return false; + } + + sessionBAK->AppendNative(nsDependentCString("sessionstore.bak")); + bool exists; + if (NS_SUCCEEDED(sessionBAK->Exists(&exists)) && exists) { + sessionBAK->Remove(false); + } + return false; + } + + hr = sCoreApp->Run(sMetroApp.Get()); Log(L"Exiting CoreApplication::Run");