From 319da2c47e68b2d1b69d95d7b1a2d33e5c36014e Mon Sep 17 00:00:00 2001 From: "gijskruitbosch%gmail.com" Date: Thu, 23 Aug 2007 21:30:30 +0000 Subject: [PATCH] Bug 372453 - XULRunner apps on mac without a hiddenwindow should be able to quit r=benjamin@smedbergs.us r=joshmoz@gmail.com a=bzbarsky@mit.edu git-svn-id: svn://10.0.0.236/trunk@232966 18797224-902f-48f8-a5cc-f745e15eee43 --- .../components/startup/src/nsAppStartup.cpp | 39 ++++++++++++++++--- .../appshell/public/nsIAppShellService.idl | 7 ++++ .../xpfe/appshell/src/nsAppShellService.cpp | 11 +++++- mozilla/xpfe/appshell/src/nsAppShellService.h | 1 + 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/mozilla/toolkit/components/startup/src/nsAppStartup.cpp b/mozilla/toolkit/components/startup/src/nsAppStartup.cpp index 6ec6fa545ca..b91b7a2e7a2 100644 --- a/mozilla/toolkit/components/startup/src/nsAppStartup.cpp +++ b/mozilla/toolkit/components/startup/src/nsAppStartup.cpp @@ -207,9 +207,33 @@ nsAppStartup::Quit(PRUint32 aMode) if (!mRestart) mRestart = aMode & eRestart; - if (ferocity == eConsiderQuit && mConsiderQuitStopper == 0) { - // attempt quit if the last window has been unregistered/closed - ferocity = eAttemptQuit; + // If we're considering quitting, we will only do so if: + if (ferocity == eConsiderQuit) { + if (mConsiderQuitStopper == 0) { + // there are no windows... + ferocity = eAttemptQuit; + } +#ifdef XP_MACOSX + else if (mConsiderQuitStopper == 1) { + // ... or there is only a hiddenWindow left, and it's useless: + nsCOMPtr appShell + (do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); + + // Failure shouldn't be fatal, but will abort quit attempt: + if (!appShell) + return NS_OK; + + PRBool usefulHiddenWindow; + appShell->GetApplicationProvidedHiddenWindow(&usefulHiddenWindow); + nsCOMPtr hiddenWindow; + appShell->GetHiddenWindow(getter_AddRefs(hiddenWindow)); + // If the one window is useful, we won't quit: + if (!hiddenWindow || usefulHiddenWindow) + return NS_OK; + + ferocity = eAttemptQuit; + } +#endif } /* Currently ferocity can never have the value of eForceQuit here. @@ -369,8 +393,13 @@ nsAppStartup::ExitLastWindowClosingSurvivalArea(void) NS_ASSERTION(mConsiderQuitStopper > 0, "consider quit stopper out of bounds"); --mConsiderQuitStopper; - if (!mShuttingDown && mRunning && mConsiderQuitStopper == 0) - Quit(eAttemptQuit); +#ifdef XP_MACOSX + if (!mShuttingDown && mRunning && (mConsiderQuitStopper <= 1)) + Quit(eConsiderQuit); +#else + if (!mShuttingDown && mRunning && (mConsiderQuitStopper == 0)) + Quit(eConsiderQuit); +#endif return NS_OK; } diff --git a/mozilla/xpfe/appshell/public/nsIAppShellService.idl b/mozilla/xpfe/appshell/public/nsIAppShellService.idl index 65416fbf8b3..e5b5c98fa6b 100644 --- a/mozilla/xpfe/appshell/public/nsIAppShellService.idl +++ b/mozilla/xpfe/appshell/public/nsIAppShellService.idl @@ -110,6 +110,13 @@ interface nsIAppShellService : nsISupports void getHiddenWindowAndJSContext(out nsIDOMWindowInternal aHiddenDOMWindow, out JSContext aJSContext); + /** + * Return true if the application hidden window was provided by the + * application. If it wasn't, the default hidden window was used. This will + * usually be false on all non-mac platforms. + */ + readonly attribute boolean applicationProvidedHiddenWindow; + /** * Add a window to the application's registry of windows. These windows * are generally shown in the Windows taskbar, and the application diff --git a/mozilla/xpfe/appshell/src/nsAppShellService.cpp b/mozilla/xpfe/appshell/src/nsAppShellService.cpp index 6b0bdf0b07c..11e3c82f4a8 100644 --- a/mozilla/xpfe/appshell/src/nsAppShellService.cpp +++ b/mozilla/xpfe/appshell/src/nsAppShellService.cpp @@ -84,7 +84,8 @@ class nsIAppShell; nsAppShellService::nsAppShellService() : mXPCOMShuttingDown(PR_FALSE), - mModalWindowCount(0) + mModalWindowCount(0), + mApplicationProvidedHiddenWindow(PR_FALSE) { nsCOMPtr obs (do_GetService("@mozilla.org/observer-service;1")); @@ -162,6 +163,7 @@ nsAppShellService::CreateHiddenWindow(nsIAppShell* aAppShell) nsXPIDLCString prefVal; rv = prefBranch->GetCharPref("browser.hiddenWindowChromeURL", getter_Copies(prefVal)); const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL; + mApplicationProvidedHiddenWindow = prefVal.get() ? PR_TRUE : PR_FALSE; #else static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL; PRUint32 chromeMask = nsIWebBrowserChrome::CHROME_ALL; @@ -446,6 +448,13 @@ nsAppShellService::GetHiddenWindowAndJSContext(nsIDOMWindowInternal **aWindow, return rv; } +NS_IMETHODIMP +nsAppShellService::GetApplicationProvidedHiddenWindow(PRBool* aAPHW) +{ + *aAPHW = mApplicationProvidedHiddenWindow; + return NS_OK; +} + /* * Register a new top level window (created elsewhere) */ diff --git a/mozilla/xpfe/appshell/src/nsAppShellService.h b/mozilla/xpfe/appshell/src/nsAppShellService.h index ee31907232b..de8d9960d3a 100644 --- a/mozilla/xpfe/appshell/src/nsAppShellService.h +++ b/mozilla/xpfe/appshell/src/nsAppShellService.h @@ -76,6 +76,7 @@ protected: nsRefPtr mHiddenWindow; PRPackedBool mXPCOMShuttingDown; PRUint16 mModalWindowCount; + PRPackedBool mApplicationProvidedHiddenWindow; }; #endif