diff --git a/mozilla/browser/components/nsBrowserGlue.js b/mozilla/browser/components/nsBrowserGlue.js index 24cd18bc913..079f3ce6d0c 100644 --- a/mozilla/browser/components/nsBrowserGlue.js +++ b/mozilla/browser/components/nsBrowserGlue.js @@ -67,6 +67,13 @@ function BrowserGlue() { BrowserGlue.prototype = { _saveSession: false, + _setPrefToSaveSession: function() + { + var prefBranch = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + prefBranch.setBoolPref("browser.sessionstore.resume_session_once", true); + }, + // nsIObserver implementation observe: function(subject, topic, data) { @@ -98,11 +105,14 @@ BrowserGlue.prototype = { break; case "quit-application-granted": if (this._saveSession) { - var prefBranch = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch); - prefBranch.setBoolPref("browser.sessionstore.resume_session_once", true); + this._setPrefToSaveSession(); } break; + case "session-save": + this._setPrefToSaveSession(); + subject.QueryInterface(Ci.nsISupportsPRBool); + subject.data = true; + break; } } , @@ -120,6 +130,7 @@ BrowserGlue.prototype = { osvr.addObserver(this, "browser:purge-session-history", false); osvr.addObserver(this, "quit-application-requested", false); osvr.addObserver(this, "quit-application-granted", false); + osvr.addObserver(this, "session-save", false); }, // cleanup (called on application shutdown) @@ -136,6 +147,7 @@ BrowserGlue.prototype = { osvr.removeObserver(this, "browser:purge-session-history"); osvr.removeObserver(this, "quit-application-requested"); osvr.removeObserver(this, "quit-application-granted"); + osvr.removeObserver(this, "session-save"); }, _onAppDefaults: function() diff --git a/mozilla/toolkit/xre/nsNativeAppSupportUnix.cpp b/mozilla/toolkit/xre/nsNativeAppSupportUnix.cpp index 807697be75d..076ae20a5d4 100644 --- a/mozilla/toolkit/xre/nsNativeAppSupportUnix.cpp +++ b/mozilla/toolkit/xre/nsNativeAppSupportUnix.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Michael Wu (original author) + * Michael Ventnor * * 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 @@ -44,6 +45,8 @@ #include "nsIAppStartup.h" #include "nsServiceManagerUtils.h" #include "prlink.h" +#include "nsXREDirProvider.h" +#include "nsReadableUtils.h" #include #include @@ -82,9 +85,11 @@ typedef void (*_gnome_client_request_interaction_fn)(GnomeClient *, GnomeInteractFunction, gpointer); typedef void (*_gnome_interaction_key_return_fn)(gint, gboolean); +typedef void (*_gnome_client_set_restart_command_fn)(GnomeClient*, gint, gchar*[]); static _gnome_client_request_interaction_fn gnome_client_request_interaction; static _gnome_interaction_key_return_fn gnome_interaction_key_return; +static _gnome_client_set_restart_command_fn gnome_client_set_restart_command; void interact_cb(GnomeClient *client, gint key, GnomeDialogType type, gpointer data) @@ -109,9 +114,58 @@ gboolean save_yourself_cb(GnomeClient *client, gint phase, GnomeInteractStyle interact, gboolean fast, gpointer user_data) { - if (interact == GNOME_INTERACT_ANY) - gnome_client_request_interaction(client, GNOME_DIALOG_NORMAL, - interact_cb, nsnull); + if (!shutdown) + return TRUE; + + nsCOMPtr obsServ = + do_GetService("@mozilla.org/observer-service;1"); + + nsCOMPtr didSaveSession = + do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID); + + if (!obsServ || !didSaveSession) + return TRUE; // OOM + + didSaveSession->SetData(PR_FALSE); + obsServ->NotifyObservers(didSaveSession, "session-save", nsnull); + + PRBool status; + didSaveSession->GetData(&status); + + // Didn't save, or no way of saving. So signal for quit-application. + if (!status) { + if (interact == GNOME_INTERACT_ANY) + gnome_client_request_interaction(client, GNOME_DIALOG_NORMAL, + interact_cb, nsnull); + return TRUE; + } + + // Tell GNOME the command for restarting us so that we can be part of XSMP session restore + NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!"); + nsCOMPtr executablePath; + nsresult rv; + + PRBool dummy; + rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath)); + + if (NS_SUCCEEDED(rv)) { + nsCAutoString path; + char* argv[1]; + + // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does + nsCAutoString leafName; + rv = executablePath->GetNativeLeafName(leafName); + if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) { + leafName.SetLength(leafName.Length() - strlen("-bin")); + executablePath->SetNativeLeafName(leafName); + } + + executablePath->GetNativePath(path); + argv[0] = (char*)(path.get()); + + gnome_client_set_restart_command(client, 1, argv); + } + return TRUE; } @@ -163,8 +217,7 @@ nsNativeAppSupportUnix::Start(PRBool *aRetVal) setenv(accEnv, "0", 1); #endif - char *argv[2] = { "gecko", "--disable-crash-dialog" }; - gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), 2, argv, NULL); + gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), gArgc, gArgv, NULL); #ifdef ACCESSIBILITY if (accOldValue) { @@ -182,6 +235,8 @@ nsNativeAppSupportUnix::Start(PRBool *aRetVal) PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_request_interaction"); gnome_interaction_key_return = (_gnome_interaction_key_return_fn) PR_FindFunctionSymbol(gnomeuiLib, "gnome_interaction_key_return"); + gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn) + PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command"); _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn) PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");