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