From cec1b90a752794091032994865e79062d6ce3e6f Mon Sep 17 00:00:00 2001 From: Dimitar Zhekov Date: Thu, 8 Nov 2012 18:04:47 +0100 Subject: Handle multiple interactive session save (bug #5379). Additionnaly, we now use SmSaveGlobal on log out / shutdown without session save which avoids data loss. Previously clients would not save anything on log out without session save. Based on original work by Chris Bainbridge (chris.bainbridge@gmail.com). --- xfce4-session/xfsm-manager.c | 81 +++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c index 3078d6a9..92ae8e36 100644 --- a/xfce4-session/xfsm-manager.c +++ b/xfce4-session/xfsm-manager.c @@ -96,6 +96,7 @@ struct _XfsmManager XfsmManagerState state; XfsmShutdownType shutdown_type; + gboolean save_session; gboolean session_chooser; gchar *session_name; @@ -225,6 +226,7 @@ xfsm_manager_init (XfsmManager *manager) manager->session_chooser = FALSE; manager->failsafe_mode = TRUE; manager->shutdown_type = XFSM_SHUTDOWN_LOGOUT; + manager->save_session = TRUE; manager->pending_properties = g_queue_new (); manager->starting_properties = g_queue_new (); @@ -981,7 +983,9 @@ xfsm_manager_interact (XfsmManager *manager, XfsmClient *cl = lp->data; if (xfsm_client_get_state (cl) == XFSM_CLIENT_INTERACTING) { - xfsm_client_set_state (cl, XFSM_CLIENT_WAITFORINTERACT); + /* a client is already interacting, so new client has to wait */ + xfsm_client_set_state (client, XFSM_CLIENT_WAITFORINTERACT); + xfsm_manager_cancel_client_save_timeout(manager, client); return; } } @@ -1158,44 +1162,47 @@ xfsm_manager_save_yourself_global (XfsmManager *manager, } #endif - if (!shutdown || shutdown_save) + /* don't save the session if shutting down without save */ + manager->save_session = !shutdown || shutdown_save; + + if (save_type == SmSaveBoth && !manager->save_session) { - xfsm_manager_set_state (manager, - shutdown - ? XFSM_MANAGER_SHUTDOWN - : XFSM_MANAGER_CHECKPOINT); + /* saving the session, so clients should + * (prompt to) save the user data only */ + save_type = SmSaveGlobal; + } - /* handle legacy applications first! */ + xfsm_manager_set_state (manager, + shutdown + ? XFSM_MANAGER_SHUTDOWN + : XFSM_MANAGER_CHECKPOINT); + + /* handle legacy applications first! */ + if (manager->save_session) xfsm_legacy_perform_session_save (); - for (lp = g_queue_peek_nth_link (manager->running_clients, 0); - lp; - lp = lp->next) - { - XfsmClient *client = lp->data; - XfsmProperties *properties = xfsm_client_get_properties (client); - const gchar *program; - - /* xterm's session management is broken, so we won't - * send a SAVE YOURSELF to xterms */ - program = xfsm_properties_get_string (properties, SmProgram); - if (program != NULL && strcasecmp (program, "xterm") == 0) - continue; + for (lp = g_queue_peek_nth_link (manager->running_clients, 0); + lp; + lp = lp->next) + { + XfsmClient *client = lp->data; + XfsmProperties *properties = xfsm_client_get_properties (client); + const gchar *program; - if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL) - { - SmsSaveYourself (xfsm_client_get_sms_connection (client), save_type, shutdown, - interact_style, fast); - } + /* xterm's session management is broken, so we won't + * send a SAVE YOURSELF to xterms */ + program = xfsm_properties_get_string (properties, SmProgram); + if (program != NULL && strcasecmp (program, "xterm") == 0) + continue; - xfsm_client_set_state (client, XFSM_CLIENT_SAVING); - xfsm_manager_start_client_save_timeout (manager, client); + if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL) + { + SmsSaveYourself (xfsm_client_get_sms_connection (client), save_type, shutdown, + interact_style, fast); } - } - else - { - /* shutdown session without saving */ - xfsm_manager_perform_shutdown (manager); + + xfsm_client_set_state (client, XFSM_CLIENT_SAVING); + xfsm_manager_start_client_save_timeout (manager, client); } } @@ -1267,7 +1274,12 @@ xfsm_manager_save_yourself_done (XfsmManager *manager, XfsmClient *client, gboolean success) { - if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVING && xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL) + /* In xfsm_manager_interact_done we send SmsShutdownCancelled to clients in + XFSM_CLIENT_WAITFORINTERACT state. They respond with SmcSaveYourselfDone + (xsmp_shutdown_cancelled in libxfce4ui library) so we allow it here. */ + if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVING && + xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL && + xfsm_client_get_state (client) != XFSM_CLIENT_WAITFORINTERACT) { xfsm_verbose ("Client Id = %s send SAVE YOURSELF DONE, while not being " "in save mode. Prepare to be nuked!\n", @@ -1539,7 +1551,8 @@ xfsm_manager_complete_saveyourself (XfsmManager *manager) xfsm_verbose ("Manager finished SAVE YOURSELF, session data will be stored now.\n\n"); /* all clients done, store session data */ - xfsm_manager_store_session (manager); + if (manager->save_session) + xfsm_manager_store_session (manager); if (manager->state == XFSM_MANAGER_CHECKPOINT) { -- cgit v1.2.1