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) {
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)
@@ -146,8 +146,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 +231,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)
@@ -33,6 +33,8 @@ gchar**     gsm_util_get_app_dirs
 
 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;
 }
 
@@ -623,6 +626,7 @@ xsmp_save (GsmClient *client,
         GKeyFile *keyfile;
         char     *desktop_file_path = NULL;
         char     *exec_program = NULL;
+        char     *exec_discard = NULL;
         char     *startup_id = NULL;
         GError   *local_error;
 
@@ -632,6 +636,10 @@ xsmp_save (GsmClient *client,
         local_error = NULL;
 
         desktop_file_path = get_desktop_file_path (GSM_XSMP_CLIENT (client));
+        exec_program = xsmp_get_restart_command (client);
+        if (!exec_program) {
+                goto out;
+        }
 
         keyfile = create_client_key_file (client,
                                           desktop_file_path,
@@ -650,15 +658,22 @@ xsmp_save (GsmClient *client,
                                "X-GNOME-Autostart-startup-id",
                                startup_id);
 
-        exec_program = xsmp_get_restart_command (client);
         g_key_file_set_string (keyfile,
                                G_KEY_FILE_DESKTOP_GROUP,
                                G_KEY_FILE_DESKTOP_KEY_EXEC,
                                exec_program);
 
+        exec_discard = xsmp_get_discard_command (client);
+        if (exec_discard)
+                g_key_file_set_string (keyfile,
+                                       G_KEY_FILE_DESKTOP_GROUP,
+                                       "X-GNOME-Autostart-discard-exec",
+                                       exec_discard);
+
 out:
         g_free (desktop_file_path);
         g_free (exec_program);
+        g_free (exec_discard);
         g_free (startup_id);
 
         if (local_error != NULL) {
@@ -690,6 +705,7 @@ xsmp_query_end_session (GsmClient *clien
                         GError   **error)
 {
         gboolean forceful;
+        int      save_type;
 
         if (GSM_XSMP_CLIENT (client)->priv->conn == NULL) {
                 g_set_error (error,
@@ -700,7 +716,14 @@ xsmp_query_end_session (GsmClient *clien
         }
 
         forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL);
-        do_save_yourself (GSM_XSMP_CLIENT (client), SmSaveGlobal, forceful);
+
+        if (flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) {
+                save_type = SmSaveBoth;
+        } else {
+                save_type = SmSaveGlobal;
+        }
+
+        do_save_yourself (GSM_XSMP_CLIENT (client), save_type, forceful);
         return TRUE;
 }
 
@@ -709,7 +732,7 @@ xsmp_end_session (GsmClient *client,
                   guint      flags,
                   GError   **error)
 {
-        gboolean forceful;
+        gboolean phase2;
 
         if (GSM_XSMP_CLIENT (client)->priv->conn == NULL) {
                 g_set_error (error,
@@ -719,8 +742,26 @@ xsmp_end_session (GsmClient *client,
                 return FALSE;
         }
 
-        forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL);
-        do_save_yourself (GSM_XSMP_CLIENT (client), SmSaveGlobal, forceful);
+        phase2 = (flags & GSM_CLIENT_END_SESSION_FLAG_LAST);
+
+        if (phase2) {
+                xsmp_save_yourself_phase2 (client);
+        } else {
+                gboolean forceful;
+                int      save_type;
+
+                forceful = (flags & GSM_CLIENT_END_SESSION_FLAG_FORCEFUL);
+
+                if (flags & GSM_CLIENT_END_SESSION_FLAG_SAVE) {
+                        save_type = SmSaveBoth;
+                } else {
+                        save_type = SmSaveGlobal;
+                }
+
+                do_save_yourself (GSM_XSMP_CLIENT (client),
+                                  save_type, forceful);
+        }
+
         return TRUE;
 }
 
@@ -1114,21 +1155,13 @@ save_yourself_phase2_request_callback (S
         g_debug ("GsmXSMPClient: Client '%s' received SaveYourselfPhase2Request",
                  client->priv->description);
 
-        /* Treat this just like a SaveYourselfDone */
-        if (client->priv->current_save_yourself == SmSaveLocal) {
-                client->priv->current_save_yourself = -1;
-                SmsSaveComplete (client->priv->conn);
-        } else {
-                client->priv->current_save_yourself = -1;
-        }
+        client->priv->current_save_yourself = -1;
 
         /* this is a valid response to SaveYourself and therefore
            may be a response to a QES or ES */
-        gdm_client_end_session_response (GSM_CLIENT (client),
-                                         TRUE,
+        gsm_client_end_session_response (GSM_CLIENT (client),
+                                         TRUE, TRUE, FALSE,
                                          NULL);
-
-        /* FIXME: change priority so this client runs at the end? */
 }
 
 static void
@@ -1137,17 +1170,20 @@ interact_request_callback (SmsConn   con
                            int       dialog_type)
 {
         GsmXSMPClient *client = manager_data;
+#if 0
         gboolean       res;
         GError        *error;
+#endif
 
         g_debug ("GsmXSMPClient: Client '%s' received InteractRequest(%s)",
                  client->priv->description,
                  dialog_type == SmDialogNormal ? "Dialog" : "Errors");
 
-        gdm_client_end_session_response (GSM_CLIENT (client),
-                                         FALSE,
+        gsm_client_end_session_response (GSM_CLIENT (client),
+                                         FALSE, FALSE, FALSE,
                                          _("This program is blocking log out."));
 
+#if 0
         /* Can't just call back with Interact because session client
            grabs the keyboard!  So, we try to get it to release
            grabs by telling it we've cancelled the shutdown.
@@ -1159,6 +1195,8 @@ interact_request_callback (SmsConn   con
                 g_warning ("Unable to cancel end session: %s", error->message);
                 g_error_free (error);
         }
+#endif
+        xsmp_interact (GSM_CLIENT (client));
 }
 
 static void
@@ -1172,8 +1210,8 @@ interact_done_callback (SmsConn   conn,
                  client->priv->description,
                  cancel_shutdown ? "True" : "False");
 
-        gdm_client_end_session_response (GSM_CLIENT (client),
-                                         TRUE,
+        gsm_client_end_session_response (GSM_CLIENT (client),
+                                         TRUE, FALSE, cancel_shutdown,
                                          NULL);
 }
 
@@ -1188,22 +1226,15 @@ save_yourself_done_callback (SmsConn   c
                  client->priv->description,
                  success ? "True" : "False");
 
-        if (client->priv->current_save_yourself == SmSaveLocal) {
-                client->priv->current_save_yourself = -1;
-                SmsSaveComplete (client->priv->conn);
-        } else {
-                client->priv->current_save_yourself = -1;
-        }
+        client->priv->current_save_yourself = -1;
+        SmsSaveComplete (client->priv->conn);
 
-        /* If success is false then the application still has
-           unsafe data.  We may also have tricked it into sending
-           us this message when we faked the ShutdownCancel to
-           break its grabs. */
-        if (success) {
-                gdm_client_end_session_response (GSM_CLIENT (client),
-                                                 TRUE,
-                                                 NULL);
-        }
+        /* If success is false then the application couldn't save data. Nothing
+         * the session manager can do about, though. FIXME: we could display a
+         * dialog about this, I guess. */
+        gsm_client_end_session_response (GSM_CLIENT (client),
+                                         TRUE, FALSE, FALSE,
+                                         NULL);
 
         if (client->priv->next_save_yourself) {
                 int save_type = client->priv->next_save_yourself;
Index: gsm-session-save.c
===================================================================
--- gsm-session-save.c	(révision 5324)
+++ gsm-session-save.c	(copie de travail)
@@ -118,6 +118,52 @@ gsm_session_save (GsmStore  *client_stor
         }
 }
 
+static gboolean
+gsm_session_clear_one_client (const char *filename)
+{
+        gboolean  result = TRUE;
+        GKeyFile *key_file = NULL;
+        char     *discard_exec = NULL;
+
+        g_debug ("GsmSessionSave: removing '%s' from saved session", filename);
+
+        key_file = g_key_file_new ();
+        if (g_key_file_load_from_file (key_file, filename,
+                                       G_KEY_FILE_NONE, NULL)) {
+                char **argv;
+                int    argc;
+
+                discard_exec = g_key_file_get_string (key_file,
+                                                      G_KEY_FILE_DESKTOP_GROUP,
+                                                      "X-GNOME-Autostart-discard-exec",
+                                                      NULL);
+                if (!discard_exec)
+                        goto out;
+
+                if (!g_shell_parse_argv (discard_exec, &argc, &argv, NULL))
+                        goto out;
+
+                /*
+                result = g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
+                                        NULL, NULL, NULL, NULL) && result;
+                                        */
+
+                g_strfreev (argv);
+        } else {
+                result = FALSE;
+        }
+
+out:
+        if (key_file)
+                g_key_file_free (key_file);
+        if (discard_exec)
+                g_free (discard_exec);
+
+        result = (g_unlink (filename) == 0) && result;
+
+        return result;
+}
+
 gboolean
 gsm_session_clear_saved_session ()
 {
@@ -147,9 +193,7 @@ gsm_session_clear_saved_session ()
                 char *path = g_build_filename (saved_session_dir,
                                                filename, NULL);
 
-                g_debug ("GsmSessionSave: removing '%s' from saved session", path);
-
-                result = result && (g_unlink (path) == 0);
+                result = gsm_session_clear_one_client (path) && result;
 
                 g_free (path);
         }
Index: gsm-inhibit-dialog.c
===================================================================
--- gsm-inhibit-dialog.c	(révision 5324)
+++ gsm-inhibit-dialog.c	(copie de travail)
@@ -52,7 +52,7 @@
 #define GLADE_XML_FILE "gsm-inhibit-dialog.glade"
 
 #ifndef DEFAULT_ICON_SIZE
-#define DEFAULT_ICON_SIZE 64
+#define DEFAULT_ICON_SIZE 32
 #endif
 
 #ifndef DEFAULT_SNAPSHOT_SIZE
@@ -521,8 +521,7 @@ add_inhibitor (GsmInhibitDialog *dialog,
         }
 
         if (desktop_filename != NULL) {
-                /* FIXME: maybe also append the autostart dirs ? */
-                search_dirs = gsm_util_get_app_dirs ();
+                search_dirs = gsm_util_get_desktop_dirs ();
 
                 error = NULL;
                 desktop_file = egg_desktop_file_new_from_dirs (desktop_filename,
@@ -632,7 +631,7 @@ update_dialog_text (GsmInhibitDialog *di
                 header_text = _("A program is still running:");
                 description_text = _("Waiting for program to finish.  Interrupting program may cause you to lose work.");
         } else {
-                g_debug ("Found multiple entries in model");
+                g_debug ("Found multiple entries (or none) in model");
                 header_text = _("Some programs are still running:");
                 description_text = _("Waiting for programs to finish.  Interrupting these programs may cause you to lose work.");
         }
Index: gsm-dbus-client.c
===================================================================
--- gsm-dbus-client.c	(révision 5324)
+++ gsm-dbus-client.c	(copie de travail)
@@ -189,7 +189,8 @@ handle_end_session_response (GsmDBusClie
                 g_error ("No memory");
         }
 
-        gdm_client_end_session_response (GSM_CLIENT (client), is_ok, reason);
+        gsm_client_end_session_response (GSM_CLIENT (client),
+                                         is_ok, FALSE, FALSE, reason);
 
 
         if (! dbus_connection_send (client->priv->connection, reply, NULL)) {
