1 From 9f3077be682355e1cd07e9a9463e76307292208c Mon Sep 17 00:00:00 2001
2 From: Dimitar Zhekov <hamster@mbox.contact.bg>
3 Date: Thu, 30 Aug 2012 20:52:14 +0000
4 Subject: Handle multiple interactive session save (bug #5379).
6 Additionnaly, we now use SmSaveGlobal on log out / shutdown without
7 session save which avoids data loss. Previously clients would not save
8 anything on log out without session save.
10 Based on original work by Chris Bainbridge (chris.bainbridge@gmail.com).
12 diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c
13 index bf6a446..35811c5 100644
14 --- a/xfce4-session/xfsm-manager.c
15 +++ b/xfce4-session/xfsm-manager.c
16 @@ -98,6 +98,7 @@ struct _XfsmManager
18 XfsmShutdownType shutdown_type;
19 XfsmShutdown *shutdown_helper;
20 + gboolean save_session;
22 gboolean session_chooser;
24 @@ -230,6 +231,7 @@ xfsm_manager_init (XfsmManager *manager)
25 manager->failsafe_mode = TRUE;
26 manager->shutdown_type = XFSM_SHUTDOWN_LOGOUT;
27 manager->shutdown_helper = xfsm_shutdown_get ();
28 + manager->save_session = TRUE;
30 manager->pending_properties = g_queue_new ();
31 manager->starting_properties = g_queue_new ();
32 @@ -989,7 +991,9 @@ xfsm_manager_interact (XfsmManager *manager,
33 XfsmClient *cl = lp->data;
34 if (xfsm_client_get_state (cl) == XFSM_CLIENT_INTERACTING)
36 - xfsm_client_set_state (cl, XFSM_CLIENT_WAITFORINTERACT);
37 + /* a client is already interacting, so new client has to wait */
38 + xfsm_client_set_state (client, XFSM_CLIENT_WAITFORINTERACT);
39 + xfsm_manager_cancel_client_save_timeout(manager, client);
43 @@ -1138,44 +1142,47 @@ xfsm_manager_save_yourself_global (XfsmManager *manager,
47 - if (!shutdown || shutdown_save)
48 + /* don't save the session if shutting down without save */
49 + manager->save_session = !shutdown || shutdown_save;
51 + if (save_type == SmSaveBoth && !manager->save_session)
53 - xfsm_manager_set_state (manager,
55 - ? XFSM_MANAGER_SHUTDOWN
56 - : XFSM_MANAGER_CHECKPOINT);
57 + /* saving the session, so clients should
58 + * (prompt to) save the user data only */
59 + save_type = SmSaveGlobal;
62 - /* handle legacy applications first! */
63 - xfsm_legacy_perform_session_save ();
64 + xfsm_manager_set_state (manager,
66 + ? XFSM_MANAGER_SHUTDOWN
67 + : XFSM_MANAGER_CHECKPOINT);
69 - for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
73 - XfsmClient *client = lp->data;
74 - XfsmProperties *properties = xfsm_client_get_properties (client);
75 - const gchar *program;
76 + /* handle legacy applications first! */
77 + if (manager->save_session)
78 + xfsm_legacy_perform_session_save ();
80 - /* xterm's session management is broken, so we won't
81 - * send a SAVE YOURSELF to xterms */
82 - program = xfsm_properties_get_string (properties, SmProgram);
83 - if (program != NULL && strcasecmp (program, "xterm") == 0)
85 + for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
89 + XfsmClient *client = lp->data;
90 + XfsmProperties *properties = xfsm_client_get_properties (client);
91 + const gchar *program;
93 - if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL)
95 - SmsSaveYourself (xfsm_client_get_sms_connection (client), save_type, shutdown,
96 - interact_style, fast);
98 + /* xterm's session management is broken, so we won't
99 + * send a SAVE YOURSELF to xterms */
100 + program = xfsm_properties_get_string (properties, SmProgram);
101 + if (program != NULL && strcasecmp (program, "xterm") == 0)
104 - xfsm_client_set_state (client, XFSM_CLIENT_SAVING);
105 - xfsm_manager_start_client_save_timeout (manager, client);
106 + if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL)
108 + SmsSaveYourself (xfsm_client_get_sms_connection (client), save_type, shutdown,
109 + interact_style, fast);
114 - /* shutdown session without saving */
115 - xfsm_manager_perform_shutdown (manager);
117 + xfsm_client_set_state (client, XFSM_CLIENT_SAVING);
118 + xfsm_manager_start_client_save_timeout (manager, client);
122 @@ -1249,7 +1256,12 @@ xfsm_manager_save_yourself_done (XfsmManager *manager,
126 - if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVING && xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL)
127 + /* In xfsm_manager_interact_done we send SmsShutdownCancelled to clients in
128 + XFSM_CLIENT_WAITFORINTERACT state. They respond with SmcSaveYourselfDone
129 + (xsmp_shutdown_cancelled in libxfce4ui library) so we allow it here. */
130 + if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVING &&
131 + xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL &&
132 + xfsm_client_get_state (client) != XFSM_CLIENT_WAITFORINTERACT)
134 xfsm_verbose ("Client Id = %s send SAVE YOURSELF DONE, while not being "
135 "in save mode. Prepare to be nuked!\n",
136 @@ -1521,7 +1533,8 @@ xfsm_manager_complete_saveyourself (XfsmManager *manager)
137 xfsm_verbose ("Manager finished SAVE YOURSELF, session data will be stored now.\n\n");
139 /* all clients done, store session data */
140 - xfsm_manager_store_session (manager);
141 + if (manager->save_session)
142 + xfsm_manager_store_session (manager);
144 if (manager->state == XFSM_MANAGER_CHECKPOINT)