Bug 386002, Move tryToClose calls on shutdown, r=benjamin

This commit is contained in:
flamingice@sourmilk.net 2007-07-16 10:55:54 -07:00
Родитель a376eec6d6
Коммит 09aeed6d39
14 изменённых файлов: 178 добавлений и 129 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -48,7 +48,6 @@ XPIDL_MODULE = appstartup
XPIDLSRCS = \
nsIAppStartup.idl \
nsICloseAllWindows.idl \
nsIUserInfo.idl \
$(NULL)

Просмотреть файл

@ -81,6 +81,6 @@ endif
endif
endif
EXTRA_COMPONENTS = nsCloseAllWindows.js
EXTRA_COMPONENTS = nsTryToClose.js
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -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<nsIWindowMediator> 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<nsIWindowMediator> mediator
(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
if (mediator) {
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
mediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
if (windowEnumerator) {
while (1) {
PRBool more;
if (NS_FAILED(rv = windowEnumerator->HasMoreElements(&more)) || !more)
break;
nsCOMPtr<nsISupports> isupports;
rv = windowEnumerator->GetNext(getter_AddRefs(isupports));
if (NS_FAILED(rv))
break;
nsCOMPtr<nsIDOMWindowInternal> window = do_QueryInterface(isupports);
NS_ASSERTION(window, "not an nsIDOMWindowInternal");
if (!window)
continue;
window->Close();
}
}
if (ferocity == eAttemptQuit) {
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
ferocity = eForceQuit; // assume success
@ -350,6 +326,32 @@ nsAppStartup::AttemptingQuit(PRBool aAttempt)
mAttemptingQuit = aAttempt;
}
void
nsAppStartup::CloseAllWindows()
{
nsCOMPtr<nsIWindowMediator> mediator
(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
mediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
if (!windowEnumerator)
return;
PRBool more;
while (NS_SUCCEEDED(windowEnumerator->HasMoreElements(&more)) && more) {
nsCOMPtr<nsISupports> isupports;
if (NS_FAILED(windowEnumerator->GetNext(getter_AddRefs(isupports))))
break;
nsCOMPtr<nsIDOMWindowInternal> 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<nsICloseAllWindows> 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<nsIProfileChangeStatus> changeStatus(do_QueryInterface(aSubject));
if (changeStatus)
changeStatus->VetoChange();
}
CloseAllWindows();
ExitLastWindowClosingSurvivalArea();
} else if (!strcmp(aTopic, "xul-window-registered")) {
EnterLastWindowClosingSurvivalArea();

Просмотреть файл

@ -74,6 +74,7 @@ private:
~nsAppStartup() { }
void AttemptingQuit(PRBool aAttempt);
void CloseAllWindows();
friend class nsAppExitEvent;

Просмотреть файл

@ -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 <flamingice@sourmilk.net> (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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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<nsICloseAllWindows> closer =
do_CreateInstance("@mozilla.org/appshell/closeallwindows;1", &rv);
nsCOMPtr<nsIObserverService> obsServ =
do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_FAILED(rv))
return errAEEventNotHandled;
PRBool doQuit;
rv = closer->CloseAll(askSave != eSaveNo, &doQuit);
nsCOMPtr<nsISupportsPRBool> 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<nsIAppStartup> 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;
}