SOURCES: gnome-session-saving.patch (NEW) - fix session saving (will be mer...
patrys
patrys at pld-linux.org
Wed Mar 18 12:30:06 CET 2009
Author: patrys Date: Wed Mar 18 11:30:06 2009 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- fix session saving (will be merged upstream in 2.26.1)
---- Files affected:
SOURCES:
gnome-session-saving.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/gnome-session-saving.patch
diff -u /dev/null SOURCES/gnome-session-saving.patch:1.1
--- /dev/null Wed Mar 18 12:30:07 2009
+++ SOURCES/gnome-session-saving.patch Wed Mar 18 12:30:00 2009
@@ -0,0 +1,1101 @@
+Index: gsm-manager.c
+===================================================================
+--- gsm-manager.c (révision 5324)
++++ gsm-manager.c (copie de travail)
+@@ -99,6 +99,7 @@ struct GsmManagerPrivate
+ gboolean forceful_logout;
+ GSList *query_clients;
+ guint query_timeout_id;
++ GSList *next_query_clients;
+
+ GtkWidget *inhibit_dialog;
+
+@@ -137,6 +138,9 @@ static void gsm_manager_class_init
+ static void gsm_manager_init (GsmManager *manager);
+ static void gsm_manager_finalize (GObject *object);
+
++static gboolean auto_save_is_enabled (GsmManager *manager);
++static void maybe_save_session (GsmManager *manager);
++
+ static gpointer manager_object = NULL;
+
+ G_DEFINE_TYPE (GsmManager, gsm_manager, G_TYPE_OBJECT)
+@@ -343,9 +347,15 @@ phase_num_to_name (guint phase)
+ case GSM_MANAGER_PHASE_END_SESSION:
+ name = "END_SESSION";
+ break;
++ case GSM_MANAGER_PHASE_END_SESSION_LAST:
++ name = "END_SESSION_LAST";
++ break;
+ case GSM_MANAGER_PHASE_EXIT:
+ name = "EXIT";
+ break;
++ case GSM_MANAGER_PHASE_EXIT_NOW:
++ name = "EXIT_NOW";
++ break;
+ default:
+ g_assert_not_reached ();
+ break;
+@@ -368,6 +378,11 @@ end_phase (GsmManager *manager)
+ g_slist_free (manager->priv->query_clients);
+ manager->priv->query_clients = NULL;
+
++ if (manager->priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
++ g_slist_free (manager->priv->next_query_clients);
++ manager->priv->next_query_clients = NULL;
++ }
++
+ if (manager->priv->phase_timeout_id > 0) {
+ g_source_remove (manager->priv->phase_timeout_id);
+ manager->priv->phase_timeout_id = 0;
+@@ -375,11 +390,7 @@ end_phase (GsmManager *manager)
+
+ manager->priv->phase++;
+
+- if (manager->priv->phase == GSM_MANAGER_PHASE_EXIT) {
+- gtk_main_quit ();
+- } else {
+- start_phase (manager);
+- }
++ start_phase (manager);
+ }
+
+ static void
+@@ -424,8 +435,10 @@ on_phase_timeout (GsmManager *manager)
+ break;
+ case GSM_MANAGER_PHASE_QUERY_END_SESSION:
+ case GSM_MANAGER_PHASE_END_SESSION:
++ case GSM_MANAGER_PHASE_END_SESSION_LAST:
+ break;
+ case GSM_MANAGER_PHASE_EXIT:
++ case GSM_MANAGER_PHASE_EXIT_NOW:
+ break;
+ default:
+ g_assert_not_reached ();
+@@ -548,6 +561,9 @@ do_phase_end_session (GsmManager *manage
+ if (manager->priv->forceful_logout) {
+ data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
+ }
++ if (auto_save_is_enabled (manager)) {
++ data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE;
++ }
+
+ if (manager->priv->phase_timeout_id > 0) {
+ g_source_remove (manager->priv->phase_timeout_id);
+@@ -568,6 +584,103 @@ do_phase_end_session (GsmManager *manage
+ }
+
+ static gboolean
++_client_end_session_last (GsmClient *client,
++ ClientEndSessionData *data)
++{
++ gboolean ret;
++ GError *error;
++
++ error = NULL;
++ ret = gsm_client_end_session (client, data->flags, &error);
++ if (! ret) {
++ g_warning ("Unable to query client: %s", error->message);
++ g_error_free (error);
++ /* FIXME: what should we do if we can't communicate with client? */
++ } else {
++ g_debug ("GsmManager: adding client to end-session clients: %s", gsm_client_peek_id (client));
++ data->manager->priv->query_clients = g_slist_prepend (data->manager->priv->query_clients,
++ client);
++ }
++
++ return FALSE;
++}
++
++static void
++do_phase_end_session_last (GsmManager *manager)
++{
++ ClientEndSessionData data;
++
++ data.manager = manager;
++ data.flags = 0;
++
++ if (manager->priv->forceful_logout) {
++ data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
++ }
++ if (auto_save_is_enabled (manager)) {
++ data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE;
++ }
++ data.flags |= GSM_CLIENT_END_SESSION_FLAG_LAST;
++
++ if (manager->priv->phase_timeout_id > 0) {
++ g_source_remove (manager->priv->phase_timeout_id);
++ manager->priv->phase_timeout_id = 0;
++ }
++
++ if (g_slist_length (manager->priv->next_query_clients) > 0) {
++ manager->priv->phase_timeout_id = g_timeout_add_seconds (10,
++ (GSourceFunc)on_phase_timeout,
++ manager);
++
++ g_slist_foreach (manager->priv->next_query_clients,
++ (GFunc)_client_end_session_last,
++ &data);
++ } else {
++ if (data.flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) {
++ maybe_save_session (manager);
++ }
++
++ end_phase (manager);
++ }
++}
++
++static gboolean
++_client_stop (const char *id,
++ GsmClient *client,
++ gpointer user_data)
++{
++ gboolean ret;
++ GError *error;
++
++ error = NULL;
++ ret = gsm_client_stop (client, &error);
++ if (! ret) {
++ g_warning ("Unable to stop client: %s", error->message);
++ g_error_free (error);
++ /* FIXME: what should we do if we can't communicate with client? */
++ } else {
++ g_debug ("GsmManager: stopped client: %s", gsm_client_peek_id (client));
++ }
++
++ return FALSE;
++}
++
++static void
++do_phase_exit (GsmManager *manager)
++{
++ if (gsm_store_size (manager->priv->clients) > 0) {
++ manager->priv->phase_timeout_id = g_timeout_add_seconds (10,
++ (GSourceFunc)on_phase_timeout,
++ manager);
++
++ gsm_store_foreach (manager->priv->clients,
++ (GsmStoreFunc)_client_stop,
++ NULL);
++ } else {
++ end_phase (manager);
++ }
++}
++
++static gboolean
+ _client_query_end_session (const char *id,
+ GsmClient *client,
+ ClientEndSessionData *data)
+@@ -677,7 +790,20 @@ inhibitor_is_jit (gpointer key,
+ static void
+ cancel_end_session (GsmManager *manager)
+ {
++ /* just ignore if received outside of shutdown */
++ if (manager->priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
++ return;
++ }
++
+ /* switch back to running phase */
++ g_debug ("GsmManager: Cancelling the end of session");
++
++ /* remove the dialog before we remove the inhibitors, else the dialog
++ * will activate itself automatically when the last inhibitor will be
++ * removed */
++ if (manager->priv->inhibit_dialog)
++ gtk_widget_destroy (GTK_WIDGET (manager->priv->inhibit_dialog));
++ manager->priv->inhibit_dialog = NULL;
+
+ /* clear all JIT inhibitors */
+ gsm_store_foreach_remove (manager->priv->inhibitors,
+@@ -981,6 +1107,9 @@ do_phase_query_end_session (GsmManager *
+ if (manager->priv->forceful_logout) {
+ data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
+ }
++ /* We only query if an app is ready to log out, so we don't use
++ * GSM_CLIENT_END_SESSION_FLAG_SAVE here.
++ */
+
+ debug_clients (manager);
+ g_debug ("GsmManager: sending query-end-session to clients forceful:%d", manager->priv->forceful_logout);
+@@ -1013,6 +1142,10 @@ start_phase (GsmManager *manager)
+ manager->priv->pending_apps = NULL;
+ g_slist_free (manager->priv->query_clients);
+ manager->priv->query_clients = NULL;
++ if (manager->priv->phase < GSM_MANAGER_PHASE_END_SESSION) {
++ g_slist_free (manager->priv->next_query_clients);
++ manager->priv->next_query_clients = NULL;
++ }
+
+ if (manager->priv->query_timeout_id > 0) {
+ g_source_remove (manager->priv->query_timeout_id);
+@@ -1042,7 +1175,14 @@ start_phase (GsmManager *manager)
+ case GSM_MANAGER_PHASE_END_SESSION:
+ do_phase_end_session (manager);
+ break;
++ case GSM_MANAGER_PHASE_END_SESSION_LAST:
++ do_phase_end_session_last (manager);
++ break;
+ case GSM_MANAGER_PHASE_EXIT:
++ do_phase_exit (manager);
++ break;
++ case GSM_MANAGER_PHASE_EXIT_NOW:
++ gtk_main_quit ();
+ break;
+ default:
+ g_assert_not_reached ();
+@@ -1533,7 +1673,7 @@ on_xsmp_client_register_request (GsmXSMP
+ }
+
+ static gboolean
+-auto_save_is_enabled(GsmManager *manager)
++auto_save_is_enabled (GsmManager *manager)
+ {
+ GError *error;
+ gboolean auto_save;
+@@ -1573,7 +1713,7 @@ maybe_save_session (GsmManager *manager)
+ /* We only allow session saving when session is running or when
+ * logging out */
+ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING &&
+- manager->priv->phase != GSM_MANAGER_PHASE_END_SESSION) {
++ manager->priv->phase != GSM_MANAGER_PHASE_END_SESSION_LAST) {
+ goto out;
+ }
+
+@@ -1593,6 +1733,8 @@ out:
+ static void
+ on_client_end_session_response (GsmClient *client,
+ gboolean is_ok,
++ gboolean do_last,
++ gboolean cancel,
+ const char *reason,
+ GsmManager *manager)
+ {
+@@ -1601,7 +1743,12 @@ on_client_end_session_response (GsmClien
+ return;
+ }
+
+- g_debug ("GsmManager: Response from end session request: is-ok=%d reason=%s", is_ok, reason);
++ g_debug ("GsmManager: Response from end session request: is-ok=%d do-last=%d cancel=%d reason=%s", is_ok, do_last, cancel, reason);
++
++ if (cancel) {
++ cancel_end_session (manager);
++ return;
++ }
+
+ manager->priv->query_clients = g_slist_remove (manager->priv->query_clients, client);
+
+@@ -1643,6 +1790,11 @@ on_client_end_session_response (GsmClien
+ (gpointer)gsm_client_peek_id (client));
+ }
+
++ if (do_last) {
++ manager->priv->next_query_clients = g_slist_prepend (manager->priv->next_query_clients,
++ client);
++ }
++
+ if (manager->priv->query_clients == NULL
+ && gsm_store_size (manager->priv->inhibitors) == 0) {
+ if (manager->priv->query_timeout_id > 0) {
+@@ -2564,7 +2716,7 @@ gsm_manager_shutdown (GsmManager *manage
+ g_set_error (error,
+ GSM_MANAGER_ERROR,
+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
+- "Logout interface is only available during the Running phase");
++ "Shutdown interface is only available during the Running phase");
+ return FALSE;
+ }
+
+Index: gsm-util.c
+===================================================================
+--- gsm-util.c (révision 5324)
++++ gsm-util.c (copie de travail)
+@@ -128,7 +128,7 @@ ensure_dir_exists (const char *dir)
+ if (g_file_test (dir, G_FILE_TEST_IS_DIR))
+ return TRUE;
+
+- if (g_mkdir_with_parents (dir, 488) == 0)
++ if (g_mkdir_with_parents (dir, 0755) == 0)
+ return TRUE;
+
+ if (errno == EEXIST)
+@@ -139,6 +139,42 @@ ensure_dir_exists (const char *dir)
+ return FALSE;
+ }
+
++gchar *
++gsm_util_get_tmp_session_dir (void)
++{
++ char *tmp;
++ gboolean exists;
++
++ tmp = g_build_filename (g_get_user_config_dir (),
++ "gnome-session",
++ "saved-session.new",
++ NULL);
++
++ exists = ensure_dir_exists (tmp);
++
++ if (G_UNLIKELY (!exists)) {
++ g_warning ("GsmSessionSave: could not create directory for saved session: %s", tmp);
++ g_free (tmp);
++ return NULL;
++ } else {
++ /* make sure it's empty */
++ GDir *dir;
++ const char *filename;
++
++ dir = g_dir_open (tmp, 0, NULL);
++ if (dir) {
++ while ((filename = g_dir_read_name (dir))) {
++ char *path = g_build_filename (tmp, filename,
++ NULL);
++ g_unlink (path);
++ }
++ g_dir_close (dir);
++ }
++ }
++
++ return tmp;
++}
++
+ const gchar *
+ gsm_util_get_saved_session_dir (void)
+ {
+@@ -146,8 +182,7 @@ gsm_util_get_saved_session_dir (void)
+ gboolean exists;
+
+ _saved_session_dir =
+- g_build_filename (g_get_home_dir (),
+- ".gnome2",
++ g_build_filename (g_get_user_config_dir (),
+ "gnome-session",
+ "saved-session",
+ NULL);
+@@ -232,6 +267,43 @@ gsm_util_get_app_dirs ()
+ return (char **) g_ptr_array_free (dirs, FALSE);
+ }
+
++char **
++gsm_util_get_desktop_dirs ()
++{
++ char **apps;
++ char **autostart;
++ char **result;
++ int size;
++ int i;
++
++ apps = gsm_util_get_app_dirs ();
++ autostart = gsm_util_get_autostart_dirs ();
++
++ size = 0;
++ for (i = 0; apps[i] != NULL; i++) { size++; }
++ for (i = 0; autostart[i] != NULL; i++) { size++; }
++ size += 2; /* saved session + last NULL */
++
++ result = g_new (char *, size + 1);
++
++ for (i = 0; apps[i] != NULL; i++) {
++ result[i] = apps[i];
++ }
++ g_free (apps);
++ size = i;
++
++ for (i = 0; autostart[i] != NULL; i++) {
++ result[size + i] = autostart[i];
++ }
++ g_free (autostart);
++ size = size + i;
++
++ result[size] = g_strdup (gsm_util_get_saved_session_dir ());
++ result[size + 1] = NULL;
++
++ return result;
++}
++
+ gboolean
+ gsm_util_text_is_blank (const char *str)
+ {
+Index: gsm-client.c
+===================================================================
+--- gsm-client.c (révision 5324)
++++ gsm-client.c (copie de travail)
+@@ -324,9 +324,9 @@ gsm_client_class_init (GsmClientClass *k
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, end_session_response),
+ NULL, NULL,
+- gsm_marshal_VOID__BOOLEAN_STRING,
++ gsm_marshal_VOID__BOOLEAN_BOOLEAN_BOOLEAN_STRING,
+ G_TYPE_NONE,
+- 2, G_TYPE_BOOLEAN, G_TYPE_STRING);
++ 4, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING);
+
+ g_object_class_install_property (object_class,
+ PROP_STARTUP_ID,
+@@ -520,9 +520,12 @@ gsm_client_save (GsmClient *client,
+ }
+
+ void
+-gdm_client_end_session_response (GsmClient *client,
++gsm_client_end_session_response (GsmClient *client,
+ gboolean is_ok,
++ gboolean do_last,
++ gboolean cancel,
+ const char *reason)
+ {
+- g_signal_emit (client, signals[END_SESSION_RESPONSE], 0, is_ok, reason);
++ g_signal_emit (client, signals[END_SESSION_RESPONSE], 0,
++ is_ok, do_last, cancel, reason);
+ }
+Index: gsm-manager.h
+===================================================================
+--- gsm-manager.h (révision 5324)
++++ gsm-manager.h (copie de travail)
+@@ -83,7 +83,9 @@ typedef enum {
+ /* shutting down */
+ GSM_MANAGER_PHASE_QUERY_END_SESSION,
+ GSM_MANAGER_PHASE_END_SESSION,
+- GSM_MANAGER_PHASE_EXIT
++ GSM_MANAGER_PHASE_END_SESSION_LAST, /* for apps that want to be done after all other apps */
++ GSM_MANAGER_PHASE_EXIT,
++ GSM_MANAGER_PHASE_EXIT_NOW
+ } GsmManagerPhase;
+
+ typedef enum
+Index: gsm-marshal.list
+===================================================================
+--- gsm-marshal.list (révision 5324)
++++ gsm-marshal.list (copie de travail)
+@@ -1,2 +1,2 @@
+ BOOLEAN:POINTER
+-VOID:BOOLEAN,STRING
++VOID:BOOLEAN,BOOLEAN,BOOLEAN,STRING
+Index: gsm-util.h
+===================================================================
+--- gsm-util.h (révision 5324)
++++ gsm-util.h (copie de travail)
+@@ -27,12 +27,16 @@ G_BEGIN_DECLS
+ char * gsm_util_find_desktop_file_for_app_name (const char *app_name,
+ char **dirs);
+
++gchar *gsm_util_get_tmp_session_dir (void);
++
+ const char *gsm_util_get_saved_session_dir (void);
+
+ gchar** gsm_util_get_app_dirs (void);
+
+ gchar** gsm_util_get_autostart_dirs (void);
+
++gchar ** gsm_util_get_desktop_dirs (void);
++
+ gboolean gsm_util_text_is_blank (const char *str);
+
+ void gsm_util_init_error (gboolean fatal,
+Index: gsm-client.h
+===================================================================
+--- gsm-client.h (révision 5324)
++++ gsm-client.h (copie de travail)
+@@ -55,7 +55,9 @@ typedef enum {
+ } GsmClientRestartStyle;
+
+ typedef enum {
+- GSM_CLIENT_END_SESSION_FLAG_FORCEFUL = 1 << 0
++ GSM_CLIENT_END_SESSION_FLAG_FORCEFUL = 1 << 0,
++ GSM_CLIENT_END_SESSION_FLAG_SAVE = 1 << 1,
++ GSM_CLIENT_END_SESSION_FLAG_LAST = 1 << 2
+ } GsmClientEndSessionFlag;
+
+ struct _GsmClient
+@@ -72,6 +74,8 @@ struct _GsmClientClass
+ void (*disconnected) (GsmClient *client);
+ void (*end_session_response) (GsmClient *client,
+ gboolean ok,
++ gboolean do_last,
++ gboolean cancel,
+ const char *reason);
+
+ /* virtual methods */
+@@ -156,8 +160,10 @@ gboolean gsm_client_get_uni
+
+ /* private */
+
+-void gdm_client_end_session_response (GsmClient *client,
++void gsm_client_end_session_response (GsmClient *client,
+ gboolean is_ok,
++ gboolean do_last,
++ gboolean cancel,
+ const char *reason);
+
+ G_END_DECLS
+Index: gsm-xsmp-client.c
+===================================================================
+--- gsm-xsmp-client.c (révision 5324)
++++ gsm-xsmp-client.c (copie de travail)
+@@ -403,7 +403,6 @@ xsmp_get_restart_command (GsmClient *cli
+ return prop_to_command (prop);
+ }
+
+-#if 0
+ static char *
+ xsmp_get_discard_command (GsmClient *client)
+ {
+@@ -417,7 +416,6 @@ xsmp_get_discard_command (GsmClient *cli
+
+ return prop_to_command (prop);
+ }
+-#endif
+
+ static void
+ do_save_yourself (GsmXSMPClient *client,
+@@ -439,6 +437,8 @@ do_save_yourself (GsmXSMPClient *client,
+ client->priv->next_save_yourself = save_type;
+ } else {
+ client->priv->current_save_yourself = save_type;
++ /* make sure we don't have anything queued */
++ client->priv->next_save_yourself = -1;
+
+ switch (save_type) {
+ case SmSaveLocal:
+@@ -470,7 +470,6 @@ do_save_yourself (GsmXSMPClient *client,
+ }
+ }
+
+-#if 0
+ static void
+ xsmp_save_yourself_phase2 (GsmClient *client)
+ {
+@@ -490,7 +489,6 @@ xsmp_interact (GsmClient *client)
+
+ SmsInteract (xsmp->priv->conn);
+ }
+-#endif
+
+ static gboolean
+ xsmp_cancel_end_session (GsmClient *client,
+@@ -509,6 +507,11 @@ xsmp_cancel_end_session (GsmClient *clie
+ }
+
+ SmsShutdownCancelled (xsmp->priv->conn);
++
++ /* reset the state */
++ xsmp->priv->current_save_yourself = -1;
++ xsmp->priv->next_save_yourself = -1;
++
+ return TRUE;
+ }
+
+@@ -620,9 +623,10 @@ static GKeyFile *
+ xsmp_save (GsmClient *client,
+ GError **error)
+ {
+- GKeyFile *keyfile;
++ GKeyFile *keyfile = NULL;
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list