Commit cec1b90a authored by Dimitar Zhekov's avatar Dimitar Zhekov Committed by Jérôme Guelfucci

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).
parent f0795f6f
......@@ -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)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment