gnome-session r5295 - in trunk: . gnome-session



Author: lucasr
Date: Tue Feb 24 01:09:25 2009
New Revision: 5295
URL: http://svn.gnome.org/viewvc/gnome-session?rev=5295&view=rev

Log:
Merge branch 'session-saving'

Added:
   trunk/gnome-session/gsm-session-save.c
   trunk/gnome-session/gsm-session-save.h
      - copied, changed from r5294, /trunk/gnome-session/gsm-util.h
Removed:
   trunk/gnome-session/gsm-resumed-app.c
   trunk/gnome-session/gsm-resumed-app.h
Modified:
   trunk/ChangeLog
   trunk/gnome-session/Makefile.am
   trunk/gnome-session/gsm-autostart-app.c
   trunk/gnome-session/gsm-client.c
   trunk/gnome-session/gsm-client.h
   trunk/gnome-session/gsm-dbus-client.c
   trunk/gnome-session/gsm-manager.c
   trunk/gnome-session/gsm-util.c
   trunk/gnome-session/gsm-util.h
   trunk/gnome-session/gsm-xsmp-client.c
   trunk/gnome-session/main.c

Modified: trunk/gnome-session/Makefile.am
==============================================================================
--- trunk/gnome-session/Makefile.am	(original)
+++ trunk/gnome-session/Makefile.am	Tue Feb 24 01:09:25 2009
@@ -59,8 +59,6 @@
 	gsm-app.c				\
 	gsm-autostart-app.h			\
 	gsm-autostart-app.c			\
-	gsm-resumed-app.h			\
-	gsm-resumed-app.c			\
 	gsm-client.c				\
 	gsm-client.h				\
 	gsm-xsmp-client.h			\
@@ -96,6 +94,8 @@
 	gsm-inhibitor.c				\
 	gsm-manager.c				\
 	gsm-manager.h				\
+	gsm-session-save.c			\
+	gsm-session-save.h			\
 	gsm-xsmp-server.c			\
 	gsm-xsmp-server.h			\
 	$(NULL)

Modified: trunk/gnome-session/gsm-autostart-app.c
==============================================================================
--- trunk/gnome-session/gsm-autostart-app.c	(original)
+++ trunk/gnome-session/gsm-autostart-app.c	Tue Feb 24 01:09:25 2009
@@ -419,7 +419,14 @@
         /* this must only be done on first load */
         switch (app->priv->launch_type) {
         case AUTOSTART_LAUNCH_SPAWN:
-                startup_id = gsm_util_generate_startup_id ();
+                startup_id =
+                        egg_desktop_file_get_string (app->priv->desktop_file,
+                                                     "X-GNOME-Autostart-startup-id",
+                                                     NULL);
+
+                if (startup_id == NULL) {
+                        startup_id = gsm_util_generate_startup_id ();
+                }
                 break;
         case AUTOSTART_LAUNCH_ACTIVATE:
                 startup_id = g_strdup (dbus_name);

Modified: trunk/gnome-session/gsm-client.c
==============================================================================
--- trunk/gnome-session/gsm-client.c	(original)
+++ trunk/gnome-session/gsm-client.c	Tue Feb 24 01:09:25 2009
@@ -23,6 +23,8 @@
 
 #include <dbus/dbus-glib.h>
 
+#include "eggdesktopfile.h"
+
 #include "gsm-marshal.h"
 #include "gsm-client.h"
 #include "gsm-client-glue.h"
@@ -506,6 +508,15 @@
         g_signal_emit (client, signals[DISCONNECTED], 0);
 }
 
+GKeyFile *
+gsm_client_save (GsmClient *client,
+                 GError   **error)
+{
+        g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
+
+        return GSM_CLIENT_GET_CLASS (client)->impl_save (client, error);
+}
+
 void
 gdm_client_end_session_response (GsmClient  *client,
                                  gboolean    is_ok,

Modified: trunk/gnome-session/gsm-client.h
==============================================================================
--- trunk/gnome-session/gsm-client.h	(original)
+++ trunk/gnome-session/gsm-client.h	Tue Feb 24 01:09:25 2009
@@ -22,6 +22,7 @@
 #ifndef __GSM_CLIENT_H__
 #define __GSM_CLIENT_H__
 
+#include <glib.h>
 #include <glib-object.h>
 #include <sys/types.h>
 
@@ -87,6 +88,8 @@
                                                               GError   **error);
         gboolean              (*impl_stop)                   (GsmClient *client,
                                                               GError   **error);
+        GKeyFile *            (*impl_save)                   (GsmClient *client,
+                                                              GError   **error);
 };
 
 typedef enum
@@ -130,6 +133,8 @@
 
 void                  gsm_client_disconnected               (GsmClient  *client);
 
+GKeyFile             *gsm_client_save                       (GsmClient  *client,
+                                                             GError    **error);
 /* exported to bus */
 gboolean              gsm_client_stop                       (GsmClient  *client,
                                                              GError    **error);

Modified: trunk/gnome-session/gsm-dbus-client.c
==============================================================================
--- trunk/gnome-session/gsm-dbus-client.c	(original)
+++ trunk/gnome-session/gsm-dbus-client.c	Tue Feb 24 01:09:25 2009
@@ -412,6 +412,19 @@
         G_OBJECT_CLASS (gsm_dbus_client_parent_class)->finalize (object);
 }
 
+static GKeyFile *
+dbus_client_save (GsmClient *client,
+                  GError   **error)
+{
+        g_debug ("GsmDBusClient: saving client with id %s",
+                 gsm_client_peek_id (client));
+
+        /* FIXME: We still don't support client saving for D-Bus
+         * session clients */
+
+        return NULL;
+}
+
 static gboolean
 dbus_client_stop (GsmClient *client,
                   GError   **error)
@@ -651,6 +664,7 @@
         object_class->set_property         = gsm_dbus_client_set_property;
         object_class->dispose              = gsm_dbus_client_dispose;
 
+        client_class->impl_save                   = dbus_client_save;
         client_class->impl_stop                   = dbus_client_stop;
         client_class->impl_query_end_session      = dbus_client_query_end_session;
         client_class->impl_end_session            = dbus_client_end_session;

Modified: trunk/gnome-session/gsm-manager.c
==============================================================================
--- trunk/gnome-session/gsm-manager.c	(original)
+++ trunk/gnome-session/gsm-manager.c	Tue Feb 24 01:09:25 2009
@@ -52,7 +52,6 @@
 #include "gsm-dbus-client.h"
 
 #include "gsm-autostart-app.h"
-#include "gsm-resumed-app.h"
 
 #include "gsm-util.h"
 #include "gdm.h"
@@ -60,6 +59,7 @@
 #include "gsm-inhibit-dialog.h"
 #include "gsm-consolekit.h"
 #include "gsm-power-manager.h"
+#include "gsm-session-save.h"
 
 #define GSM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_MANAGER, GsmManagerPrivate))
 
@@ -79,6 +79,9 @@
 #define KEY_DESKTOP_DIR           "/desktop/gnome/session"
 #define KEY_IDLE_DELAY            KEY_DESKTOP_DIR "/idle_delay"
 
+#define KEY_GNOME_SESSION_DIR     "/apps/gnome-session/options"
+#define KEY_AUTOSAVE              KEY_GNOME_SESSION_DIR "/auto_save_session"
+
 #define IS_STRING_EMPTY(x) ((x)==NULL||(x)[0]=='\0')
 
 struct GsmManagerPrivate
@@ -93,7 +96,7 @@
         GsmManagerPhase         phase;
         guint                   phase_timeout_id;
         GSList                 *pending_apps;
-        gboolean                forceful;
+        gboolean                forceful_logout;
         GSList                 *query_clients;
         guint                   query_timeout_id;
 
@@ -280,7 +283,9 @@
                         /* Kill client in case condition if false and make sure it won't
                          * be automatically restarted by adding the client to
                          * condition_clients */
-                        manager->priv->condition_clients = g_slist_prepend (manager->priv->condition_clients, client);
+                        manager->priv->condition_clients =
+                                g_slist_prepend (manager->priv->condition_clients, client);
+
                         g_debug ("GsmManager: stopping client %s for app", gsm_client_peek_id (client));
 
                         error = NULL;
@@ -540,7 +545,7 @@
         data.manager = manager;
         data.flags = 0;
 
-        if (manager->priv->forceful) {
+        if (manager->priv->forceful_logout) {
                 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
         }
 
@@ -684,7 +689,7 @@
                            NULL);
 
         gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_RUNNING);
-        manager->priv->forceful = FALSE;
+        manager->priv->forceful_logout = FALSE;
 
         start_phase (manager);
 }
@@ -806,7 +811,7 @@
                 manager_attempt_reboot (manager);
                 break;
         case GSM_LOGOUT_ACTION_LOGOUT:
-                manager->priv->forceful = TRUE;
+                manager->priv->forceful_logout = TRUE;
                 end_phase (manager);
                 break;
         default:
@@ -973,12 +978,12 @@
         data.manager = manager;
         data.flags = 0;
 
-        if (manager->priv->forceful) {
+        if (manager->priv->forceful_logout) {
                 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
         }
 
         debug_clients (manager);
-        g_debug ("GsmManager: sending query-end-session to clients forceful:%d", manager->priv->forceful);
+        g_debug ("GsmManager: sending query-end-session to clients forceful:%d", manager->priv->forceful_logout);
         gsm_store_foreach (manager->priv->clients,
                            (GsmStoreFunc)_client_query_end_session,
                            &data);
@@ -1527,6 +1532,51 @@
         return handled;
 }
 
+static gboolean
+auto_save_is_enabled(GsmManager *manager)
+{
+        GError   *error;
+        gboolean  auto_save;
+
+        error = NULL;
+        auto_save = gconf_client_get_bool (manager->priv->gconf_client,
+                                           KEY_AUTOSAVE,
+                                           &error);
+
+        if (error) {
+                g_warning ("Error retrieving configuration key '%s': %s",
+                           KEY_AUTOSAVE,
+                           error->message);
+                g_error_free (error);
+
+                /* If we fail to query gconf key, disable auto save */
+                auto_save = FALSE;
+        }
+
+        return auto_save;
+}
+
+static void
+maybe_save_session (GsmManager *manager)
+{
+        GError *error;
+
+        /* 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) {
+                return;
+        }
+
+        error = NULL;
+        gsm_session_save (manager->priv->clients, &error);
+
+        if (error) {
+                g_warning ("Error saving session: %s", error->message);
+                g_error_free (error);
+        }
+}
+
 static void
 on_client_end_session_response (GsmClient  *client,
                                 gboolean    is_ok,
@@ -1587,6 +1637,10 @@
                         manager->priv->query_timeout_id = 0;
                 }
 
+                if (auto_save_is_enabled (manager)) {
+                        maybe_save_session (manager);
+                }
+
                 end_phase (manager);
         }
 }
@@ -1599,8 +1653,11 @@
         GError *error;
         int     logout_mode;
 
-        logout_mode = (show_dialog) ? GSM_MANAGER_LOGOUT_MODE_NORMAL :
-                GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION;
+        if (show_dialog) {
+                logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
+        } else {
+                logout_mode = GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION;
+        }
 
         error = NULL;
         gsm_manager_logout (manager, logout_mode, &error);
@@ -2322,10 +2379,10 @@
 
 static void
 request_logout (GsmManager *manager,
-                gboolean    forceful)
+                gboolean    forceful_logout)
 {
         g_debug ("GsmManager: requesting logout");
-        manager->priv->forceful = forceful;
+        manager->priv->forceful_logout = forceful_logout;
         end_phase (manager);
 }
 
@@ -2440,20 +2497,19 @@
 static void
 user_logout (GsmManager *manager,
              gboolean    show_confirmation,
-             gboolean    forceful)
+             gboolean    forceful_logout)
 {
-        gboolean     logout_prompt;
-        GConfClient *client;
+        gboolean logout_prompt;
 
         if (manager->priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
                 /* Already shutting down, nothing more to do */
                 return;
         }
-        client = gconf_client_get_default ();
-        logout_prompt = gconf_client_get_bool (client,
-                                               "/apps/gnome-session/options/logout_prompt",
-                                               NULL);
-        g_object_unref (client);
+
+        logout_prompt =
+               gconf_client_get_bool (manager->priv->gconf_client,
+                                      "/apps/gnome-session/options/logout_prompt",
+                                      NULL);
 
         /* Global settings overides input parameter in order to disable confirmation
          * dialog accordingly. If we're shutting down, we always show the confirmation
@@ -2463,7 +2519,7 @@
         if (logout_prompt) {
                 show_logout_dialog (manager);
         } else {
-                request_logout (manager, forceful);
+                request_logout (manager, forceful_logout);
         }
 }
 
@@ -2835,9 +2891,9 @@
                 return TRUE;
         }
 
-        inhibitor = (GsmInhibitor *)gsm_store_find (manager->priv->inhibitors,
-                                                    (GsmStoreFunc)inhibitor_has_flag,
-                                                    GUINT_TO_POINTER (flags));
+        inhibitor = (GsmInhibitor *) gsm_store_find (manager->priv->inhibitors,
+                                                     (GsmStoreFunc)inhibitor_has_flag,
+                                                     GUINT_TO_POINTER (flags));
         if (inhibitor == NULL) {
                 *is_inhibited = FALSE;
         } else {
@@ -2886,7 +2942,9 @@
         }
 
         *inhibitors = g_ptr_array_new ();
-        gsm_store_foreach (manager->priv->inhibitors, (GsmStoreFunc)listify_store_ids, inhibitors);
+        gsm_store_foreach (manager->priv->inhibitors,
+                           (GsmStoreFunc) listify_store_ids,
+                           inhibitors);
 
         return TRUE;
 }
@@ -2916,7 +2974,10 @@
 
         g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);
 
-        app = (GsmApp *)gsm_store_find (manager->priv->apps, (GsmStoreFunc)_app_has_autostart_condition, (char *)condition);
+        app = (GsmApp *) gsm_store_find (manager->priv->apps,(
+                                         GsmStoreFunc) _app_has_autostart_condition,
+                                         (char *)condition);
+
         if (app != NULL) {
                 *handled = TRUE;
         } else {
@@ -3030,40 +3091,3 @@
 
         return TRUE;
 }
-
-gboolean
-gsm_manager_add_legacy_session_apps (GsmManager *manager,
-                                     const char *path)
-{
-        GKeyFile *saved;
-        int       num_clients;
-        int       i;
-
-        g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);
-        g_return_val_if_fail (path != NULL, FALSE);
-
-        saved = g_key_file_new ();
-        if (!g_key_file_load_from_file (saved, path, 0, NULL)) {
-                /* FIXME: error handling? */
-                g_key_file_free (saved);
-                return FALSE;
-        }
-
-        num_clients = g_key_file_get_integer (saved,
-                                              "Default",
-                                              "num_clients",
-                                              NULL);
-        for (i = 0; i < num_clients; i++) {
-                GsmApp *app;
-
-                app = gsm_resumed_app_new_from_legacy_session (saved, i);
-                if (app != NULL) {
-                        append_app (manager, app);
-                        g_object_unref (app);
-                }
-        }
-
-        g_key_file_free (saved);
-
-        return TRUE;
-}

Added: trunk/gnome-session/gsm-session-save.c
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gsm-session-save.c	Tue Feb 24 01:09:25 2009
@@ -0,0 +1,158 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ * gsm-session-save.c
+ * Copyright (C) 2008 Lucas Rocha.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "gsm-util.h"
+#include "gsm-client.h"
+
+#include "gsm-session-save.h"
+
+static gboolean
+save_one_client (char     *id,
+                 GObject  *object,
+                 GError  **error)
+{
+        GsmClient  *client;
+        GKeyFile   *keyfile;
+        char       *path = NULL;
+        char       *filename = NULL;
+        char       *contents = NULL;
+        const char *saved_session_dir;
+        gsize       length = 0;
+        GError     *local_error;
+
+        client = GSM_CLIENT (object);
+
+        local_error = NULL;
+
+        keyfile = gsm_client_save (client, &local_error);
+
+        if (keyfile == NULL || local_error) {
+                goto out;
+        }
+
+        contents = g_key_file_to_data (keyfile, &length, &local_error);
+
+        if (local_error) {
+                goto out;
+        }
+
+        saved_session_dir = gsm_util_get_saved_session_dir ();
+
+        if (saved_session_dir == NULL) {
+                goto out;
+        }
+
+        filename = g_strdup_printf ("%s.desktop",
+                                    gsm_client_peek_startup_id (client));
+
+        path = g_build_filename (saved_session_dir, filename, NULL);
+
+        g_file_set_contents (path,
+                             contents,
+                             length,
+                             &local_error);
+
+        if (local_error) {
+                goto out;
+        }
+
+        g_debug ("GsmSessionSave: saved client %s to %s", id, filename);
+
+out:
+        if (keyfile != NULL) {
+                g_key_file_free (keyfile);
+        }
+
+        g_free (contents);
+        g_free (filename);
+        g_free (path);
+
+        /* in case of any error, stop saving session */
+        if (local_error) {
+                g_propagate_error (error, local_error);
+                g_error_free (local_error);
+
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+void
+gsm_session_save (GsmStore  *client_store,
+                  GError   **error)
+{
+        gsm_session_clear_saved_session ();
+
+        g_debug ("GsmSessionSave: Saving session");
+
+        gsm_store_foreach (client_store,
+                           (GsmStoreFunc) save_one_client,
+                           error);
+
+        if (*error) {
+                g_warning ("GsmSessionSave: error saving session: %s", (*error)->message);
+                gsm_session_clear_saved_session ();
+        }
+}
+
+gboolean
+gsm_session_clear_saved_session ()
+{
+        GDir       *dir;
+        const char *saved_session_dir;
+        const char *filename;
+        gboolean    result = TRUE;
+        GError     *error;
+
+        saved_session_dir = gsm_util_get_saved_session_dir ();
+
+        g_debug ("GsmSessionSave: clearing currectly saved session at %s", saved_session_dir);
+
+        if (saved_session_dir == NULL) {
+                return FALSE;
+        }
+
+        error = NULL;
+        dir = g_dir_open (saved_session_dir, 0, &error);
+        if (error) {
+                g_warning ("GsmSessionSave: error loading saved session directory: %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        while ((filename = g_dir_read_name (dir))) {
+                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);
+
+                g_free (path);
+        }
+
+        return result;
+}

Copied: trunk/gnome-session/gsm-session-save.h (from r5294, /trunk/gnome-session/gsm-util.h)
==============================================================================
--- /trunk/gnome-session/gsm-util.h	(original)
+++ trunk/gnome-session/gsm-session-save.h	Tue Feb 24 01:09:25 2009
@@ -1,4 +1,4 @@
-/* gsm-util.h
+/* gsm-session-save.h
  * Copyright (C) 2008 Lucas Rocha.
  *
  * This program is free software; you can redistribute it and/or
@@ -17,26 +17,20 @@
  * 02111-1307, USA.
  */
 
-#ifndef __GSM_UTIL_H__
-#define __GSM_UTIL_H__
+#ifndef __GSM_SESSION_SAVE_H__
+#define __GSM_SESSION_SAVE_H__
 
 #include <glib.h>
 
-G_BEGIN_DECLS
-
-gchar**   gsm_util_get_app_dirs         (void);
+#include "gsm-store.h"
 
-gchar**   gsm_util_get_autostart_dirs   (void);
-
-gboolean  gsm_util_text_is_blank        (const char *str);
+G_BEGIN_DECLS
 
-void      gsm_util_init_error           (gboolean    fatal,
-                                         const char *format, ...);
-char *    gsm_util_generate_startup_id  (void);
+void      gsm_session_save                 (GsmStore  *client_store,
+                                            GError   **error);
 
-void      gsm_util_setenv               (const char *variable,
-                                         const char *value);
+gboolean  gsm_session_clear_saved_session  (void);
 
 G_END_DECLS
 
-#endif /* __GSM_UTIL_H__ */
+#endif /* __GSM_SESSION_SAVE_H__ */

Modified: trunk/gnome-session/gsm-util.c
==============================================================================
--- trunk/gnome-session/gsm-util.c	(original)
+++ trunk/gnome-session/gsm-util.c	Tue Feb 24 01:09:25 2009
@@ -24,15 +24,154 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include <errno.h>
+#include <string.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
 #include <gtk/gtk.h>
 
 #include <dbus/dbus-glib.h>
 
 #include "gsm-util.h"
 
+static gchar *_saved_session_dir = NULL;
+
+char *
+gsm_util_find_desktop_file_for_app_name (const char *name,
+                                         char      **autostart_dirs)
+{
+        char     *app_path;
+        char    **app_dirs;
+        GKeyFile *key_file;
+        char     *desktop_file;
+        int       i;
+
+        app_path = NULL;
+
+        app_dirs = gsm_util_get_app_dirs ();
+
+        key_file = g_key_file_new ();
+
+        desktop_file = g_strdup_printf ("%s.desktop", name);
+
+        g_debug ("GsmUtil: Looking for file '%s'", desktop_file);
+
+        for (i = 0; app_dirs[i] != NULL; i++) {
+                g_debug ("GsmUtil: Looking in '%s'", app_dirs[i]);
+        }
+
+        g_key_file_load_from_dirs (key_file,
+                                   desktop_file,
+                                   (const char **) app_dirs,
+                                   &app_path,
+                                   G_KEY_FILE_NONE,
+                                   NULL);
+
+        if (app_path != NULL) {
+                g_debug ("GsmUtil: found in XDG app dirs: '%s'", app_path);
+        }
+
+        if (app_path == NULL && autostart_dirs != NULL) {
+                g_key_file_load_from_dirs (key_file,
+                                           desktop_file,
+                                           (const char **) autostart_dirs,
+                                           &app_path,
+                                           G_KEY_FILE_NONE,
+                                           NULL);
+                if (app_path != NULL) {
+                        g_debug ("GsmUtil: found in autostart dirs: '%s'", app_path);
+                }
+
+        }
+
+        /* look for gnome vender prefix */
+        if (app_path == NULL) {
+                g_free (desktop_file);
+                desktop_file = g_strdup_printf ("gnome-%s.desktop", name);
+
+                g_key_file_load_from_dirs (key_file,
+                                           desktop_file,
+                                           (const char **) app_dirs,
+                                           &app_path,
+                                           G_KEY_FILE_NONE,
+                                           NULL);
+                if (app_path != NULL) {
+                        g_debug ("GsmUtil: found in XDG app dirs: '%s'", app_path);
+                }
+        }
+
+        if (app_path == NULL && autostart_dirs != NULL) {
+                g_key_file_load_from_dirs (key_file,
+                                           desktop_file,
+                                           (const char **) autostart_dirs,
+                                           &app_path,
+                                           G_KEY_FILE_NONE,
+                                           NULL);
+                if (app_path != NULL) {
+                        g_debug ("GsmUtil: found in autostart dirs: '%s'", app_path);
+                }
+        }
+
+        g_free (desktop_file);
+        g_key_file_free (key_file);
+
+        g_strfreev (app_dirs);
+
+        return app_path;
+}
+
+static gboolean
+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)
+                return TRUE;
+
+        if (errno == EEXIST)
+                return g_file_test (dir, G_FILE_TEST_IS_DIR);
+
+        g_warning ("GsmSessionSave: Failed to create directory %s: %s", dir, strerror (errno));
+
+        return FALSE;
+}
+
+const gchar *
+gsm_util_get_saved_session_dir (void)
+{
+        if (_saved_session_dir == NULL) {
+                gboolean exists;
+
+                _saved_session_dir =
+                        g_build_filename (g_get_home_dir (),
+                                          ".gnome2",
+                                          "gnome-session",
+                                          "saved-session",
+                                          NULL);
+
+                exists = ensure_dir_exists (_saved_session_dir);
+
+                if (G_UNLIKELY (!exists)) {
+                        static gboolean printed_warning = FALSE;
+
+                        if (!printed_warning) {
+                                g_warning ("GsmSessionSave: could not create directory for saved session: %s", _saved_session_dir);
+                                printed_warning = TRUE;
+                        }
+
+                        _saved_session_dir = NULL;
+
+                        return NULL;
+                }
+        }
+
+        return _saved_session_dir;
+}
+
+
 char **
 gsm_util_get_autostart_dirs ()
 {

Modified: trunk/gnome-session/gsm-util.h
==============================================================================
--- trunk/gnome-session/gsm-util.h	(original)
+++ trunk/gnome-session/gsm-util.h	Tue Feb 24 01:09:25 2009
@@ -24,18 +24,24 @@
 
 G_BEGIN_DECLS
 
-gchar**   gsm_util_get_app_dirs         (void);
+char *      gsm_util_find_desktop_file_for_app_name (const char  *app_name,
+                                                     char       **dirs);
 
-gchar**   gsm_util_get_autostart_dirs   (void);
+const char *gsm_util_get_saved_session_dir          (void);
 
-gboolean  gsm_util_text_is_blank        (const char *str);
+gchar**     gsm_util_get_app_dirs                   (void);
 
-void      gsm_util_init_error           (gboolean    fatal,
-                                         const char *format, ...);
-char *    gsm_util_generate_startup_id  (void);
+gchar**     gsm_util_get_autostart_dirs             (void);
 
-void      gsm_util_setenv               (const char *variable,
-                                         const char *value);
+gboolean    gsm_util_text_is_blank                  (const char *str);
+
+void        gsm_util_init_error                     (gboolean    fatal,
+                                                     const char *format, ...);
+
+char *      gsm_util_generate_startup_id            (void);
+
+void        gsm_util_setenv                         (const char *variable,
+                                                     const char *value);
 
 G_END_DECLS
 

Modified: trunk/gnome-session/gsm-xsmp-client.c
==============================================================================
--- trunk/gnome-session/gsm-xsmp-client.c	(original)
+++ trunk/gnome-session/gsm-xsmp-client.c	Tue Feb 24 01:09:25 2009
@@ -28,19 +28,19 @@
 #include <unistd.h>
 #include <errno.h>
 
+#include <gio/gio.h>
 #include <glib/gi18n.h>
 
 #include "gsm-xsmp-client.h"
 #include "gsm-marshal.h"
 
+#include "gsm-util.h"
 #include "gsm-manager.h"
 
-/* FIXME */
-#define GsmDesktopFile "_Gsm_DesktopFile"
+#define GsmDesktopFile "_GSM_DesktopFile"
 
 #define IS_STRING_EMPTY(x) ((x)==NULL||(x)[0]=='\0')
 
-
 #define GSM_XSMP_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_XSMP_CLIENT, GsmXSMPClientPrivate))
 
 struct GsmXSMPClientPrivate
@@ -389,7 +389,6 @@
         return g_string_free (str, FALSE);
 }
 
-#if 0
 static char *
 xsmp_get_restart_command (GsmClient *client)
 {
@@ -404,6 +403,7 @@
         return prop_to_command (prop);
 }
 
+#if 0
 static char *
 xsmp_get_discard_command (GsmClient *client)
 {
@@ -460,10 +460,10 @@
                                                  TRUE); /* fast */
                         } else {
                                 SmsSaveYourself (client->priv->conn,
-                                                 save_type,
-                                                 TRUE,
-                                                 SmInteractStyleAny,
-                                                 FALSE);
+                                                 save_type, /* save type */
+                                                 TRUE, /* shutdown */
+                                                 SmInteractStyleAny, /* interact style */
+                                                 FALSE /* fast */);
                         }
                         break;
                 }
@@ -512,6 +512,165 @@
         return TRUE;
 }
 
+static char *
+get_desktop_file_path (GsmXSMPClient *client)
+{
+        SmProp     *prop;
+        char       *desktop_file_path = NULL;
+        char      **dirs;
+        const char *program_name;
+
+        /* XSMP clients using eggsmclient defines a special property
+         * pointing to their respective desktop entry file */
+        prop = find_property (client, GsmDesktopFile, NULL);
+
+        if (prop) {
+                GFile *file = g_file_new_for_uri (prop->vals[0].value);
+                desktop_file_path = g_file_get_path (file);
+                g_object_unref (file);
+                goto out;
+        }
+
+        /* If we can't get desktop file from GsmDesktopFile then we
+         * try to find the desktop file from its program name */
+        prop = find_property (client, SmProgram, NULL);
+        program_name = prop->vals[0].value;
+
+        dirs = gsm_util_get_autostart_dirs ();
+
+        desktop_file_path =
+                gsm_util_find_desktop_file_for_app_name (program_name,
+                                                         dirs);
+
+        g_strfreev (dirs);
+
+out:
+        g_debug ("GsmXSMPClient: desktop file for client %s is %s",
+                 gsm_client_peek_id (GSM_CLIENT (client)),
+                 desktop_file_path ? desktop_file_path : "(null)");
+
+        return desktop_file_path;
+}
+
+static void
+set_desktop_file_keys_from_client (GsmClient *client,
+                                   GKeyFile  *keyfile)
+{
+        SmProp *prop;
+        char   *name;
+        char   *comment;
+
+        prop = find_property (GSM_XSMP_CLIENT (client), SmProgram, NULL);
+        name = g_strdup (prop->vals[0].value);
+
+        comment = g_strdup_printf ("Client %s which was automatically saved",
+                                   gsm_client_peek_startup_id (client));
+
+        g_key_file_set_string (keyfile,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_NAME,
+                               name);
+
+        g_key_file_set_string (keyfile,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_COMMENT,
+                               comment);
+
+        g_key_file_set_string (keyfile,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_ICON,
+                               "system-run");
+
+        g_key_file_set_string (keyfile,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_TYPE,
+                               "Application");
+
+        g_key_file_set_boolean (keyfile,
+                                G_KEY_FILE_DESKTOP_GROUP,
+                                G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY,
+                                TRUE);
+
+        g_free (name);
+        g_free (comment);
+}
+
+static GKeyFile *
+create_client_key_file (GsmClient   *client,
+                        const char  *desktop_file_path,
+                        GError     **error) {
+        GKeyFile *keyfile;
+
+        keyfile = g_key_file_new ();
+
+        if (desktop_file_path != NULL) {
+                g_key_file_load_from_file (keyfile,
+                                           desktop_file_path,
+                                           G_KEY_FILE_KEEP_COMMENTS |
+                                           G_KEY_FILE_KEEP_TRANSLATIONS,
+                                           error);
+        } else {
+                set_desktop_file_keys_from_client (client, keyfile);
+        }
+
+        return keyfile;
+}
+
+static GKeyFile *
+xsmp_save (GsmClient *client,
+           GError   **error)
+{
+        GKeyFile *keyfile;
+        char     *desktop_file_path = NULL;
+        char     *exec_program = NULL;
+        char     *startup_id = NULL;
+        GError   *local_error;
+
+        g_debug ("GsmXSMPClient: saving client with id %s",
+                 gsm_client_peek_id (client));
+
+        local_error = NULL;
+
+        desktop_file_path = get_desktop_file_path (GSM_XSMP_CLIENT (client));
+
+        keyfile = create_client_key_file (client,
+                                          desktop_file_path,
+                                          &local_error);
+
+        if (local_error) {
+                goto out;
+        }
+
+        g_object_get (client,
+                      "startup-id", &startup_id,
+                      NULL);
+
+        g_key_file_set_string (keyfile,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               "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);
+
+out:
+        g_free (desktop_file_path);
+        g_free (exec_program);
+        g_free (startup_id);
+
+        if (local_error != NULL) {
+                g_propagate_error (error, local_error);
+                g_key_file_free (keyfile);
+
+                return NULL;
+        }
+
+        return keyfile;
+}
+
 static gboolean
 xsmp_stop (GsmClient *client,
            GError   **error)
@@ -771,6 +930,7 @@
         object_class->get_property         = gsm_xsmp_client_get_property;
         object_class->set_property         = gsm_xsmp_client_set_property;
 
+        client_class->impl_save                   = xsmp_save;
         client_class->impl_stop                   = xsmp_stop;
         client_class->impl_query_end_session      = xsmp_query_end_session;
         client_class->impl_end_session            = xsmp_end_session;

Modified: trunk/gnome-session/main.c
==============================================================================
--- trunk/gnome-session/main.c	(original)
+++ trunk/gnome-session/main.c	Tue Feb 24 01:09:25 2009
@@ -162,90 +162,6 @@
         return TRUE;
 }
 
-static char *
-find_desktop_file_for_app_name (const char *name,
-                                char      **autostart_dirs)
-{
-        char     *app_path;
-        char    **app_dirs;
-        GKeyFile *key_file;
-        char     *desktop_file;
-        int       i;
-
-        app_path = NULL;
-
-        app_dirs = gsm_util_get_app_dirs ();
-
-        key_file = g_key_file_new ();
-
-        desktop_file = g_strdup_printf ("%s.desktop", name);
-
-        g_debug ("main: Looking for file '%s'", desktop_file);
-
-        for (i = 0; app_dirs[i] != NULL; i++) {
-                g_debug ("main: Looking in '%s'", app_dirs[i]);
-        }
-
-        g_key_file_load_from_dirs (key_file,
-                                   desktop_file,
-                                   (const char **) app_dirs,
-                                   &app_path,
-                                   G_KEY_FILE_NONE,
-                                   NULL);
-
-        if (app_path != NULL) {
-                g_debug ("main: found in XDG app dirs: '%s'", app_path);
-        }
-
-        if (app_path == NULL && autostart_dirs != NULL) {
-                g_key_file_load_from_dirs (key_file,
-                                           desktop_file,
-                                           (const char **) autostart_dirs,
-                                           &app_path,
-                                           G_KEY_FILE_NONE,
-                                           NULL);
-                if (app_path != NULL) {
-                        g_debug ("main: found in autostart dirs: '%s'", app_path);
-                }
-
-        }
-
-        /* look for gnome vender prefix */
-        if (app_path == NULL) {
-                g_free (desktop_file);
-                desktop_file = g_strdup_printf ("gnome-%s.desktop", name);
-
-                g_key_file_load_from_dirs (key_file,
-                                           desktop_file,
-                                           (const char **) app_dirs,
-                                           &app_path,
-                                           G_KEY_FILE_NONE,
-                                           NULL);
-                if (app_path != NULL) {
-                        g_debug ("main: found in XDG app dirs: '%s'", app_path);
-                }
-        }
-
-        if (app_path == NULL && autostart_dirs != NULL) {
-                g_key_file_load_from_dirs (key_file,
-                                           desktop_file,
-                                           (const char **) autostart_dirs,
-                                           &app_path,
-                                           G_KEY_FILE_NONE,
-                                           NULL);
-                if (app_path != NULL) {
-                        g_debug ("main: found in autostart dirs: '%s'", app_path);
-                }
-        }
-
-        g_free (desktop_file);
-        g_key_file_free (key_file);
-
-        g_strfreev (app_dirs);
-
-        return app_path;
-}
-
 /* This doesn't contain the required components, so we need to always
  * call append_required_apps() after a call to append_default_apps(). */
 static void
@@ -276,7 +192,7 @@
                         continue;
                 }
 
-                app_path = find_desktop_file_for_app_name (a->data, autostart_dirs);
+                app_path = gsm_util_find_desktop_file_for_app_name (a->data, autostart_dirs);
                 if (app_path != NULL) {
                         gsm_manager_add_autostart_app (manager, app_path, NULL);
                         g_free (app_path);
@@ -288,25 +204,6 @@
 }
 
 static void
-append_saved_session_apps (GsmManager *manager)
-{
-        char *session_filename;
-
-        /* try resuming from the old gnome-session's files */
-        session_filename = g_build_filename (g_get_home_dir (),
-                                             ".gnome2",
-                                             "session",
-                                             NULL);
-        if (g_file_test (session_filename, G_FILE_TEST_EXISTS)) {
-                gsm_manager_add_legacy_session_apps (manager, session_filename);
-                g_free (session_filename);
-                return;
-        }
-
-        g_free (session_filename);
-}
-
-static void
 append_required_apps (GsmManager *manager)
 {
         GSList      *required_components;
@@ -344,7 +241,7 @@
                 if (default_provider != NULL) {
                         char *app_path;
 
-                        app_path = find_desktop_file_for_app_name (default_provider, NULL);
+                        app_path = gsm_util_find_desktop_file_for_app_name (default_provider, NULL);
                         if (app_path != NULL) {
                                 gsm_manager_add_autostart_app (manager, app_path, component);
                         } else {
@@ -382,12 +279,12 @@
                 goto out;
         }
 
+        gsm_manager_add_autostart_apps_from_dir (manager, gsm_util_get_saved_session_dir ());
+
         for (i = 0; autostart_dirs[i]; i++) {
                 gsm_manager_add_autostart_apps_from_dir (manager, autostart_dirs[i]);
         }
 
-        append_saved_session_apps (manager);
-
  out:
         /* We do this at the end in case a saved session contains an
          * application that already provides one of the components. */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]