diff --git a/browser/installer/unix/packages-static b/browser/installer/unix/packages-static index db6ea237ad2d..2393a98eab96 100644 --- a/browser/installer/unix/packages-static +++ b/browser/installer/unix/packages-static @@ -206,7 +206,7 @@ bin/components/nsLoginManager.js bin/components/nsLoginManagerPrompter.js bin/components/storage-Legacy.js bin/components/jsconsole-clhandler.js -bin/components/nsCloseAllWindows.js +bin/components/nsTryToClose.js bin/components/nsDictionary.js bin/components/nsFilePicker.js bin/components/nsHelperAppDlg.js diff --git a/browser/installer/windows/packages-static b/browser/installer/windows/packages-static index 8e6eebbe2060..1a6216a028c4 100644 --- a/browser/installer/windows/packages-static +++ b/browser/installer/windows/packages-static @@ -202,7 +202,7 @@ bin\components\WebContentConverter.js bin\components\nsBrowserContentHandler.js bin\components\nsBrowserGlue.js bin\components\nsSetDefaultBrowser.js -bin\components\nsCloseAllWindows.js +bin\components\nsTryToClose.js bin\components\nsDictionary.js bin\components\nsHelperAppDlg.js bin\components\nsProxyAutoConfig.js diff --git a/layout/tools/reftest/quit.js b/layout/tools/reftest/quit.js index ab3b0fdf8c25..e5031d40603b 100644 --- a/layout/tools/reftest/quit.js +++ b/layout/tools/reftest/quit.js @@ -97,24 +97,6 @@ function goQuitApplication() throw 'goQuitApplication: no AppStartup/appShell'; } - var windowManager = Components. - classes['@mozilla.org/appshell/window-mediator;1'].getService(); - - var windowManagerInterface = windowManager. - QueryInterface(Components.interfaces.nsIWindowMediator); - - var enumerator = windowManagerInterface.getEnumerator(null); - - while (enumerator.hasMoreElements()) - { - var domWindow = enumerator.getNext(); - if (("tryToClose" in domWindow) && !domWindow.tryToClose()) - { - return false; - } - domWindow.close(); - } - try { appService.quit(forceQuit); diff --git a/testing/mochitest/tests/SimpleTest/quit.js b/testing/mochitest/tests/SimpleTest/quit.js index 5373d524a008..8b2a33973c90 100644 --- a/testing/mochitest/tests/SimpleTest/quit.js +++ b/testing/mochitest/tests/SimpleTest/quit.js @@ -127,24 +127,6 @@ function goQuitApplication() throw 'goQuitApplication: no AppStartup/appShell'; } - var windowManager = Components. - classes['@mozilla.org/appshell/window-mediator;1'].getService(); - - var windowManagerInterface = windowManager. - QueryInterface(Components.interfaces.nsIWindowMediator); - - var enumerator = windowManagerInterface.getEnumerator(null); - - while (enumerator.hasMoreElements()) - { - var domWindow = enumerator.getNext(); - if (("tryToClose" in domWindow) && !domWindow.tryToClose()) - { - return false; - } - domWindow.close(); - } - try { appService.quit(forceQuit); diff --git a/toolkit/components/startup/public/Makefile.in b/toolkit/components/startup/public/Makefile.in index 188f88cfbd48..28867d3f451b 100644 --- a/toolkit/components/startup/public/Makefile.in +++ b/toolkit/components/startup/public/Makefile.in @@ -48,7 +48,6 @@ XPIDL_MODULE = appstartup XPIDLSRCS = \ nsIAppStartup.idl \ - nsICloseAllWindows.idl \ nsIUserInfo.idl \ $(NULL) diff --git a/toolkit/components/startup/src/Makefile.in b/toolkit/components/startup/src/Makefile.in index 1d96f815bfe7..7a4f05876cb9 100644 --- a/toolkit/components/startup/src/Makefile.in +++ b/toolkit/components/startup/src/Makefile.in @@ -81,6 +81,6 @@ endif endif endif -EXTRA_COMPONENTS = nsCloseAllWindows.js +EXTRA_COMPONENTS = nsTryToClose.js include $(topsrcdir)/config/rules.mk diff --git a/toolkit/components/startup/src/nsAppStartup.cpp b/toolkit/components/startup/src/nsAppStartup.cpp index 92a12a99a069..60dc2f3ce8ab 100644 --- a/toolkit/components/startup/src/nsAppStartup.cpp +++ b/toolkit/components/startup/src/nsAppStartup.cpp @@ -42,7 +42,6 @@ #include "nsAppStartup.h" #include "nsIAppShellService.h" -#include "nsICloseAllWindows.h" #include "nsIDOMWindowInternal.h" #include "nsIInterfaceRequestor.h" #include "nsILocalFile.h" @@ -203,9 +202,6 @@ nsAppStartup::Quit(PRUint32 aMode) if (!mRestart) mRestart = aMode & eRestart; - nsCOMPtr mediator - (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); - if (ferocity == eConsiderQuit && mConsiderQuitStopper == 0) { // attempt quit if the last window has been unregistered/closed ferocity = eAttemptQuit; @@ -223,33 +219,13 @@ nsAppStartup::Quit(PRUint32 aMode) this before we forcequit because this can control whether we really quit at all. e.g. if one of these windows has an unload handler that opens a new window. Ugh. I know. */ + CloseAllWindows(); + + nsCOMPtr mediator + (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); if (mediator) { - nsCOMPtr windowEnumerator; - - mediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator)); - - if (windowEnumerator) { - - while (1) { - PRBool more; - if (NS_FAILED(rv = windowEnumerator->HasMoreElements(&more)) || !more) - break; - - nsCOMPtr isupports; - rv = windowEnumerator->GetNext(getter_AddRefs(isupports)); - if (NS_FAILED(rv)) - break; - - nsCOMPtr window = do_QueryInterface(isupports); - NS_ASSERTION(window, "not an nsIDOMWindowInternal"); - if (!window) - continue; - - window->Close(); - } - } - if (ferocity == eAttemptQuit) { + nsCOMPtr windowEnumerator; ferocity = eForceQuit; // assume success @@ -350,6 +326,32 @@ nsAppStartup::AttemptingQuit(PRBool aAttempt) mAttemptingQuit = aAttempt; } +void +nsAppStartup::CloseAllWindows() +{ + nsCOMPtr mediator + (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); + + nsCOMPtr windowEnumerator; + + mediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator)); + + if (!windowEnumerator) + return; + + PRBool more; + while (NS_SUCCEEDED(windowEnumerator->HasMoreElements(&more)) && more) { + nsCOMPtr isupports; + if (NS_FAILED(windowEnumerator->GetNext(getter_AddRefs(isupports)))) + break; + + nsCOMPtr window = do_QueryInterface(isupports); + NS_ASSERTION(window, "not an nsIDOMWindowInternal"); + if (window) + window->Close(); + } +} + NS_IMETHODIMP nsAppStartup::EnterLastWindowClosingSurvivalArea(void) { @@ -450,22 +452,8 @@ nsAppStartup::Observe(nsISupports *aSubject, { NS_ASSERTION(mAppShell, "appshell service notified before appshell built"); if (!strcmp(aTopic, "profile-change-teardown")) { - nsresult rv; EnterLastWindowClosingSurvivalArea(); - // NOTE: No early error exits because we need to execute the - // balancing ExitLastWindowClosingSurvivalArea(). - nsCOMPtr closer = - do_CreateInstance("@mozilla.org/appshell/closeallwindows;1", &rv); - NS_ASSERTION(closer, "Failed to create nsICloseAllWindows impl."); - PRBool proceedWithSwitch = PR_FALSE; - if (closer) - rv = closer->CloseAll(PR_TRUE, &proceedWithSwitch); - - if (NS_FAILED(rv) || !proceedWithSwitch) { - nsCOMPtr changeStatus(do_QueryInterface(aSubject)); - if (changeStatus) - changeStatus->VetoChange(); - } + CloseAllWindows(); ExitLastWindowClosingSurvivalArea(); } else if (!strcmp(aTopic, "xul-window-registered")) { EnterLastWindowClosingSurvivalArea(); diff --git a/toolkit/components/startup/src/nsAppStartup.h b/toolkit/components/startup/src/nsAppStartup.h index 53a1c8523512..3c0ab5f9430e 100644 --- a/toolkit/components/startup/src/nsAppStartup.h +++ b/toolkit/components/startup/src/nsAppStartup.h @@ -74,6 +74,7 @@ private: ~nsAppStartup() { } void AttemptingQuit(PRBool aAttempt); + void CloseAllWindows(); friend class nsAppExitEvent; diff --git a/toolkit/components/startup/src/nsTryToClose.js b/toolkit/components/startup/src/nsTryToClose.js new file mode 100644 index 000000000000..0d68b8679478 --- /dev/null +++ b/toolkit/components/startup/src/nsTryToClose.js @@ -0,0 +1,125 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the nsTryToClose component. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Michael Wu (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +const CID = Components.ID("{b69155f4-a8bf-453d-8653-91d1456e1d3d}"); +const CONTRACT_ID = "@mozilla.org/appshell/trytoclose;1" +const CLASS_NAME = "tryToClose Service"; + +function TryToClose() { +} + +TryToClose.prototype = { + observe: function (aSubject, aTopic, aData) { + switch (aTopic) { + case "app-startup": + var obsService = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); + obsService.addObserver(this, "quit-application-requested", true); + break; + case "quit-application-requested": + var windowMediator = Cc['@mozilla.org/appshell/window-mediator;1']. + getService(Ci.nsIWindowMediator); + var enumerator = windowMediator.getEnumerator(null); + while (enumerator.hasMoreElements()) { + var domWindow = enumerator.getNext(); + if (("tryToClose" in domWindow) && !domWindow.tryToClose()) { + aSubject.QueryInterface(Ci.nsISupportsPRBool); + aSubject.data = true; + break; + } + } + break; + } + }, + + QueryInterface: function(aIID) { + if (!aIID.equals(Ci.nsIObserver) && + !aIID.equals(Ci.nsISupportsWeakReference) && + !aIID.equals(Ci.nsISupports)) + throw Cr.NS_ERROR_NO_INTERFACE; + return this; + } +}; + +const TryToCloseFactory = { + createInstance: function(aOuter, aIID) { + if (aOuter != null) + throw Cr.NS_ERROR_NO_AGGREGATION; + + return (new TryToClose()).QueryInterface(aIID); + } +}; + +const TryToCloseModule = { + registerSelf: function(aCompMgr, aFileSpec, aLocation, aType) { + aCompMgr.QueryInterface(Ci.nsIComponentRegistrar); + aCompMgr.registerFactoryLocation(CID, CLASS_NAME, CONTRACT_ID, + aFileSpec, aLocation, aType); + + var catMan = Cc["@mozilla.org/categorymanager;1"]. + getService(Ci.nsICategoryManager); + catMan.addCategoryEntry("app-startup", CLASS_NAME, "service," + CONTRACT_ID, true, true); + }, + + unregisterSelf: function(aCompMgr, aLocation, aType) { + aCompMgr.QueryInterface(Ci.nsIComponentRegistrar); + aCompMgr.unregisterFactoryLocation(CID, aLocation); + + var catMan = Cc["@mozilla.org/categorymanager;1"]. + getService(Ci.nsICategoryManager); + catMan.deleteCategoryEntry( "app-startup", "service," + CONTRACT_ID, true); + }, + + getClassObject: function(aCompMgr, aCID, aIID) { + if (aCID.equals(CID)) + return TryToCloseFactory; + + throw Cr.NS_ERROR_NOT_REGISTERED; + }, + + canUnload: function(aCompMgr) { + return true; + } +}; + +function NSGetModule(aCompMgr, aFileSpec) { + return TryToCloseModule; +} diff --git a/toolkit/content/globalOverlay.js b/toolkit/content/globalOverlay.js index d0ac1c64bc40..bd1a28ac5c94 100644 --- a/toolkit/content/globalOverlay.js +++ b/toolkit/content/globalOverlay.js @@ -52,19 +52,9 @@ function goQuitApplication() if (!canQuitApplication()) return false; - var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(); - var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator); - var enumerator = windowManagerInterface.getEnumerator( null ); var appStartup = Components.classes['@mozilla.org/toolkit/app-startup;1']. getService(Components.interfaces.nsIAppStartup); - while ( enumerator.hasMoreElements() ) - { - var domWindow = enumerator.getNext(); - if (("tryToClose" in domWindow) && !domWindow.tryToClose()) - return false; - domWindow.close(); - }; appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit); return true; } diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index 4b1206052a19..c1d4d36a0804 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -1473,15 +1473,6 @@ function restartApp() { // Notify all windows that an application quit has been granted. os.notifyObservers(null, "quit-application-granted", null); - // Enumerate all windows and call shutdown handlers - var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator); - var windows = wm.getEnumerator(null); - while (windows.hasMoreElements()) { - var win = windows.getNext(); - if (("tryToClose" in win) && !win.tryToClose()) - return; - } Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup) .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit); } diff --git a/toolkit/mozapps/extensions/content/list.js b/toolkit/mozapps/extensions/content/list.js index 89799cf903e4..8c8a6231884f 100755 --- a/toolkit/mozapps/extensions/content/list.js +++ b/toolkit/mozapps/extensions/content/list.js @@ -215,15 +215,6 @@ function restartApp() { // Notify all windows that an application quit has been granted. os.notifyObservers(null, "quit-application-granted", null); - // Enumerate all windows and call shutdown handlers - var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator); - var windows = wm.getEnumerator(null); - while (windows.hasMoreElements()) { - var win = windows.getNext(); - if (("tryToClose" in win) && !win.tryToClose()) - return; - } Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup) .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit); } diff --git a/toolkit/mozapps/update/content/updates.js b/toolkit/mozapps/update/content/updates.js index a6c507855d6f..70ee7b9496a6 100755 --- a/toolkit/mozapps/update/content/updates.js +++ b/toolkit/mozapps/update/content/updates.js @@ -1658,17 +1658,6 @@ var gFinishedPage = { // Notify all windows that an application quit has been granted. os.notifyObservers(null, "quit-application-granted", null); - // Enumerate all windows and call shutdown handlers - var wm = - Components.classes["@mozilla.org/appshell/window-mediator;1"]. - getService(Components.interfaces.nsIWindowMediator); - var windows = wm.getEnumerator(null); - while (windows.hasMoreElements()) { - var win = windows.getNext(); - if (("tryToClose" in win) && !win.tryToClose()) - return; - } - var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]. getService(Components.interfaces.nsIAppStartup); diff --git a/toolkit/xre/nsCommandLineServiceMac.cpp b/toolkit/xre/nsCommandLineServiceMac.cpp index b20d4ac1a6a4..9d11df563038 100644 --- a/toolkit/xre/nsCommandLineServiceMac.cpp +++ b/toolkit/xre/nsCommandLineServiceMac.cpp @@ -60,7 +60,7 @@ #include "nsIWindowWatcher.h" #include "jsapi.h" #include "nsReadableUtils.h" -#include "nsICloseAllWindows.h" +#include "nsIObserverService.h" #include "nsIPrefService.h" #include "nsAEEventHandling.h" @@ -453,16 +453,26 @@ OSErr nsMacCommandLine::Quit(TAskSave askSave) { nsresult rv; - nsCOMPtr closer = - do_CreateInstance("@mozilla.org/appshell/closeallwindows;1", &rv); + nsCOMPtr obsServ = + do_GetService("@mozilla.org/observer-service;1", &rv); if (NS_FAILED(rv)) return errAEEventNotHandled; - PRBool doQuit; - rv = closer->CloseAll(askSave != eSaveNo, &doQuit); + nsCOMPtr cancelQuit = + do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID, &rv); if (NS_FAILED(rv)) return errAEEventNotHandled; - if (!doQuit) + + cancelQuit->SetData(PR_FALSE); + if (askSave != eSaveNo) { + rv = obsServ->NotifyObservers(cancelQuit, "quit-application-requested", nsnull); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + } + + PRBool abortQuit; + cancelQuit->GetData(&abortQuit); + if (abortQuit) return userCanceledErr; nsCOMPtr appStartup = @@ -470,6 +480,7 @@ OSErr nsMacCommandLine::Quit(TAskSave askSave) if (NS_FAILED(rv)) return errAEEventNotHandled; + obsServ->NotifyObservers(nsnull, "quit-application-granted", nsnull); appStartup->Quit(nsIAppStartup::eAttemptQuit); return noErr; }