gnome-session r4735 - in branches/dbus_based: . gnome-session



Author: mccann
Date: Fri Jun 13 00:14:09 2008
New Revision: 4735
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4735&view=rev

Log:
2008-06-12  William Jon McCann  <jmccann redhat com>

	* gnome-session/gsm-app.c (gsm_app_init), (set_property),
	(get_property), (dispose), (gsm_app_class_init), (gsm_app_get_id),
	(gsm_app_get_client_id), (gsm_app_get_phase), (gsm_app_is_running),
	(gsm_app_provides), (gsm_app_start), (gsm_app_stop),
	(gsm_app_exited):
	* gnome-session/gsm-app.h:
	* gnome-session/gsm-autostart-app.c (gsm_autostart_app_init),
	(gsm_autostart_app_set_desktop_file),
	(gsm_autostart_app_set_property), (gsm_autostart_app_get_property),
	(gsm_autostart_app_dispose), (if_exists_condition_cb),
	(unless_exists_condition_cb), (is_running), (is_disabled),
	(app_exited), (launch), (get_basename),
	(gsm_autostart_app_provides), (gsm_autostart_app_class_init),
	(gsm_autostart_app_new):
	* gnome-session/gsm-client-store.c:
	* gnome-session/gsm-client-store.h:
	* gnome-session/gsm-client.c (gsm_client_finalize):
	* gnome-session/gsm-manager.c (app_condition_changed),
	(_start_app), (start_phase), (append_app), (_find_app_provides),
	(append_required_apps), (gsm_manager_init), (gsm_manager_finalize),
	(initiate_shutdown):
	* gnome-session/gsm-resumed-app.c (launch), (get_basename),
	(gsm_resumed_app_class_init),
	(gsm_resumed_app_new_from_legacy_session):
	* gnome-session/gsm-resumed-app.h:
	* gnome-session/gsm-xsmp-client.c (gsm_xsmp_client_finalize):
	A bit more refactoring.



Modified:
   branches/dbus_based/ChangeLog
   branches/dbus_based/gnome-session/gsm-app.c
   branches/dbus_based/gnome-session/gsm-app.h
   branches/dbus_based/gnome-session/gsm-autostart-app.c
   branches/dbus_based/gnome-session/gsm-client-store.c
   branches/dbus_based/gnome-session/gsm-client-store.h
   branches/dbus_based/gnome-session/gsm-client.c
   branches/dbus_based/gnome-session/gsm-manager.c
   branches/dbus_based/gnome-session/gsm-resumed-app.c
   branches/dbus_based/gnome-session/gsm-resumed-app.h
   branches/dbus_based/gnome-session/gsm-xsmp-client.c

Modified: branches/dbus_based/gnome-session/gsm-app.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-app.c	(original)
+++ branches/dbus_based/gnome-session/gsm-app.c	Fri Jun 13 00:14:09 2008
@@ -24,10 +24,20 @@
 
 #include <glib.h>
 #include <string.h>
-#include <sys/wait.h>
 
 #include "gsm-app.h"
 
+#define GSM_APP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_APP, GsmAppPrivate))
+
+struct _GsmAppPrivate
+{
+        char           *id;
+
+        GsmManagerPhase phase;
+        char           *client_id;
+};
+
+
 enum {
         EXITED,
         REGISTERED,
@@ -38,74 +48,17 @@
 
 enum {
         PROP_0,
-        PROP_DESKTOP_FILE,
+        PROP_ID,
         PROP_CLIENT_ID,
+        PROP_PHASE,
         LAST_PROP
 };
 
-static void set_property (GObject *object, guint prop_id,
-                          const GValue *value, GParamSpec *pspec);
-static void get_property (GObject *object, guint prop_id,
-                          GValue *value, GParamSpec *pspec);
-static void dispose      (GObject *object);
-
-static const char *get_basename (GsmApp *app);
-static pid_t       launch       (GsmApp *app, GError **err);
-
 G_DEFINE_TYPE (GsmApp, gsm_app, G_TYPE_OBJECT)
 
 static void
 gsm_app_init (GsmApp *app)
 {
-        app->pid = -1;
-}
-
-static void
-gsm_app_class_init (GsmAppClass *app_class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (app_class);
-
-        object_class->set_property = set_property;
-        object_class->get_property = get_property;
-        object_class->dispose = dispose;
-
-        app_class->get_basename = get_basename;
-        app_class->launch = launch;
-
-        g_object_class_install_property (object_class,
-                                         PROP_DESKTOP_FILE,
-                                         g_param_spec_string ("desktop-file",
-                                                              "Desktop file",
-                                                              "Freedesktop .desktop file",
-                                                              NULL,
-                                                              G_PARAM_READWRITE));
-        g_object_class_install_property (object_class,
-                                         PROP_CLIENT_ID,
-                                         g_param_spec_string ("client-id",
-                                                              "Client ID",
-                                                              "Session management client ID",
-                                                              NULL,
-                                                              G_PARAM_READWRITE));
-
-        signals[EXITED] =
-                g_signal_new ("exited",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (GsmAppClass, exited),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
-
-        signals[REGISTERED] =
-                g_signal_new ("registered",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (GsmAppClass, registered),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
 }
 
 static void
@@ -115,55 +68,19 @@
               GParamSpec   *pspec)
 {
         GsmApp *app = GSM_APP (object);
-        const char *desktop_file;
-        char *phase;
-        GError *error = NULL;
 
         switch (prop_id) {
-        case PROP_DESKTOP_FILE:
-                if (app->desktop_file) {
-                        egg_desktop_file_free (app->desktop_file);
-                }
-                desktop_file = g_value_get_string (value);
-                if (!desktop_file) {
-                        app->desktop_file = NULL;
-                        break;
-                }
-
-                app->desktop_file = egg_desktop_file_new (desktop_file, &error);
-                if (!app->desktop_file) {
-                        g_warning ("Could not parse desktop file %s: %s",
-                                   desktop_file, error->message);
-                        g_error_free (error);
-                        break;
-                }
-
-                phase = egg_desktop_file_get_string (app->desktop_file,
-                                                     "X-GNOME-Autostart-Phase", NULL);
-                if (phase) {
-                        if (!strcmp (phase, "Initialization")) {
-                                app->phase = GSM_MANAGER_PHASE_INITIALIZATION;
-                        } else if (!strcmp (phase, "WindowManager")) {
-                                app->phase = GSM_MANAGER_PHASE_WINDOW_MANAGER;
-                        } else if (!strcmp (phase, "Panel")) {
-                                app->phase = GSM_MANAGER_PHASE_PANEL;
-                        } else if (!strcmp (phase, "Desktop")) {
-                                app->phase = GSM_MANAGER_PHASE_DESKTOP;
-                        } else {
-                                app->phase = GSM_MANAGER_PHASE_APPLICATION;
-                        }
-
-                        g_free (phase);
-                } else {
-                        app->phase = GSM_MANAGER_PHASE_APPLICATION;
-                }
-                break;
-
         case PROP_CLIENT_ID:
-                g_free (app->client_id);
-                app->client_id = g_value_dup_string (value);
+                g_free (app->priv->client_id);
+                app->priv->client_id = g_value_dup_string (value);
+                break;
+        case PROP_ID:
+                g_free (app->priv->id);
+                app->priv->id = g_value_dup_string (value);
+                break;
+        case PROP_PHASE:
+                app->priv->phase = g_value_get_int (value);
                 break;
-
         default:
                 break;
         }
@@ -178,75 +95,106 @@
         GsmApp *app = GSM_APP (object);
 
         switch (prop_id) {
-        case PROP_DESKTOP_FILE:
-                if (app->desktop_file) {
-                        g_value_set_string (value, egg_desktop_file_get_source (app->desktop_file));
-                } else {
-                        g_value_set_string (value, NULL);
-                }
-                break;
-
         case PROP_CLIENT_ID:
-                g_value_set_string (value, app->client_id);
+                g_value_set_string (value, app->priv->client_id);
+                break;
+        case PROP_ID:
+                g_value_set_string (value, app->priv->id);
+                break;
+        case PROP_PHASE:
+                g_value_set_int (value, app->priv->phase);
                 break;
-
         default:
                 break;
         }
 }
 
 static void
-dispose(GObject *object)
+dispose (GObject *object)
 {
         GsmApp *app = GSM_APP (object);
 
-        if (app->desktop_file) {
-                egg_desktop_file_free (app->desktop_file);
-                app->desktop_file = NULL;
+        if (app->priv->client_id) {
+                g_free (app->priv->client_id);
+                app->priv->client_id = NULL;
         }
+}
 
-        if (app->startup_id) {
-                g_free (app->startup_id);
-                app->startup_id = NULL;
-        }
+static void
+gsm_app_class_init (GsmAppClass *app_class)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (app_class);
 
-        if (app->client_id) {
-                g_free (app->client_id);
-                app->client_id = NULL;
-        }
+        object_class->set_property = set_property;
+        object_class->get_property = get_property;
+        object_class->dispose = dispose;
+
+        app_class->get_basename = NULL;
+        app_class->start = NULL;
+        app_class->provides = NULL;
+        app_class->is_running = NULL;
+
+        g_object_class_install_property (object_class,
+                                         PROP_PHASE,
+                                         g_param_spec_int ("phase",
+                                                           "Phase",
+                                                           "Phase",
+                                                           -1,
+                                                           G_MAXINT,
+                                                           -1,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_CLIENT_ID,
+                                         g_param_spec_string ("id",
+                                                              "ID",
+                                                              "ID",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_CLIENT_ID,
+                                         g_param_spec_string ("client-id",
+                                                              "Client ID",
+                                                              "Session management client ID",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+        signals[EXITED] =
+                g_signal_new ("exited",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsmAppClass, exited),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
+        signals[REGISTERED] =
+                g_signal_new ("registered",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsmAppClass, registered),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
 }
 
-/**
- * gsm_app_get_basename:
- * @app: a %GsmApp
- *
- * Returns an identifying name for @app, e.g. the basename of the path to
- * @app's desktop file (if any).
- *
- * Return value: an identifying name for @app, or %NULL.
- **/
 const char *
 gsm_app_get_basename (GsmApp *app)
 {
         return GSM_APP_GET_CLASS (app)->get_basename (app);
 }
 
-static const char *
-get_basename (GsmApp *app)
+const char *
+gsm_app_get_id (GsmApp *app)
 {
-        const char *location, *slash;
-
-        if (!app->desktop_file)
-                return NULL;
-
-        location = egg_desktop_file_get_source (app->desktop_file);
+        return app->priv->id;
+}
 
-        slash = strrchr (location, '/');
-        if (slash) {
-                return slash + 1;
-        } else {
-                return location;
-        }
+const char *
+gsm_app_get_client_id (GsmApp *app)
+{
+        return app->priv->client_id;
 }
 
 /**
@@ -262,17 +210,9 @@
 {
         g_return_val_if_fail (GSM_IS_APP (app), GSM_MANAGER_PHASE_APPLICATION);
 
-        return app->phase;
+        return app->priv->phase;
 }
 
-/**
- * gsm_app_is_disabled:
- * @app: a %GsmApp
- *
- * Tests if @app is disabled
- *
- * Return value: whether or not @app is disabled
- **/
 gboolean
 gsm_app_is_disabled (GsmApp *app)
 {
@@ -286,108 +226,42 @@
 }
 
 gboolean
-gsm_app_provides (GsmApp *app, const char *service)
+gsm_app_is_running (GsmApp *app)
 {
-        char **provides;
-        gsize len, i;
-
         g_return_val_if_fail (GSM_IS_APP (app), FALSE);
 
-        if (!app->desktop_file) {
-                return FALSE;
-        }
-
-        provides = egg_desktop_file_get_string_list (app->desktop_file,
-                                                     "X-GNOME-Provides",
-                                                     &len, NULL);
-        if (!provides) {
+        if (GSM_APP_GET_CLASS (app)->is_running) {
+                return GSM_APP_GET_CLASS (app)->is_running (app);
+        } else {
                 return FALSE;
         }
-
-        for (i = 0; i < len; i++) {
-                if (!strcmp (provides[i], service)) {
-                        g_strfreev (provides);
-                        return TRUE;
-                }
-        }
-
-        g_strfreev (provides);
-        return FALSE;
 }
 
-static void
-app_exited (GPid pid, gint status, gpointer data)
+gboolean
+gsm_app_provides (GsmApp *app, const char *service)
 {
-        if (WIFEXITED (status)) {
-                g_signal_emit (GSM_APP (data), signals[EXITED], 0);
-        }
-}
 
-static pid_t
-launch (GsmApp  *app,
-        GError **err)
-{
-        char *env[2] = { NULL, NULL };
-        gboolean success;
-
-        g_return_val_if_fail (app->desktop_file != NULL, (pid_t)-1);
-
-        if (egg_desktop_file_get_boolean (app->desktop_file,
-                                          "X-GNOME-Autostart-Notify", NULL) ||
-            egg_desktop_file_get_boolean (app->desktop_file,
-                                          "AutostartNotify", NULL)) {
-                env[0] = g_strdup_printf ("DESKTOP_AUTOSTART_ID=%s", app->client_id);
-        }
-
-#if 0
-        g_debug ("launching %s with client_id %s\n",
-                 gsm_app_get_basename (app), app->client_id);
-#endif
-
-        success =
-                egg_desktop_file_launch (app->desktop_file, NULL, err,
-                                         EGG_DESKTOP_FILE_LAUNCH_PUTENV, env,
-                                         EGG_DESKTOP_FILE_LAUNCH_FLAGS, G_SPAWN_DO_NOT_REAP_CHILD,
-                                         EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, &app->pid,
-                                         EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID, &app->startup_id,
-                                         NULL);
-
-        g_free (env[0]);
-
-        if (success) {
-                /* In case the app belongs to Initialization phase, we monitor
-                 * if it exits to emit proper "exited" signal to session. */
-                if (app->phase == GSM_MANAGER_PHASE_INITIALIZATION) {
-                        g_child_watch_add ((GPid) app->pid, app_exited, app);
-                }
-
-                return app->pid;
+        if (GSM_APP_GET_CLASS (app)->provides) {
+                return GSM_APP_GET_CLASS (app)->provides (app, service);
         } else {
-                return (pid_t) -1;
+                return FALSE;
         }
 }
 
-/**
- * gsm_app_launch:
- * @app: a %GsmApp
- * @err: an error pointer
- *
- * Launches @app
- *
- * Return value: the pid of the new process, or -1 on error
- **/
-pid_t
-gsm_app_launch (GsmApp *app, GError **err)
+gboolean
+gsm_app_start (GsmApp  *app,
+               GError **error)
 {
-        return GSM_APP_GET_CLASS (app)->launch (app, err);
+        return GSM_APP_GET_CLASS (app)->start (app, error);
+}
+
+gboolean
+gsm_app_stop (GsmApp  *app,
+              GError **error)
+{
+        return GSM_APP_GET_CLASS (app)->stop (app, error);
 }
 
-/**
- * gsm_app_registered:
- * @app: a %GsmApp
- *
- * Emits "registered" signal in @app
- **/
 void
 gsm_app_registered (GsmApp *app)
 {
@@ -396,3 +270,10 @@
         g_signal_emit (app, signals[REGISTERED], 0);
 }
 
+void
+gsm_app_exited (GsmApp *app)
+{
+        g_return_if_fail (GSM_IS_APP (app));
+
+        g_signal_emit (app, signals[EXITED], 0);
+}

Modified: branches/dbus_based/gnome-session/gsm-app.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-app.h	(original)
+++ branches/dbus_based/gnome-session/gsm-app.h	Fri Jun 13 00:14:09 2008
@@ -44,14 +44,8 @@
 
 struct _GsmApp
 {
-        GObject         parent;
-
-        EggDesktopFile *desktop_file;
-        GsmManagerPhase phase;
-
-        pid_t           pid;
-        char           *startup_id;
-        char           *client_id;
+        GObject        parent;
+        GsmAppPrivate *priv;
 };
 
 struct _GsmAppClass
@@ -59,25 +53,43 @@
         GObjectClass parent_class;
 
         /* signals */
-        void        (*exited)       (GsmApp *app, int status);
+        void        (*exited)       (GsmApp *app,
+                                     int     status);
         void        (*registered)   (GsmApp *app);
 
         /* virtual methods */
+        gboolean    (*start)         (GsmApp     *app,
+                                      GError    **error);
+        gboolean    (*stop)          (GsmApp     *app,
+                                      GError    **error);
+        gboolean    (*provides)      (GsmApp     *app,
+                                      const char *service);
+        gboolean    (*is_running)    (GsmApp     *app);
+
         const char *(*get_basename) (GsmApp *app);
         gboolean    (*is_disabled)  (GsmApp *app);
-        pid_t       (*launch)       (GsmApp *app, GError **err);
-        void        (*set_client)   (GsmApp *app, GsmClient *client);
+        void        (*set_client)   (GsmApp    *app,
+                                     GsmClient *client);
 };
 
 GType            gsm_app_get_type        (void) G_GNUC_CONST;
 
-const char      *gsm_app_get_basename    (GsmApp     *app);
+gboolean         gsm_app_start           (GsmApp     *app,
+                                          GError    **error);
+gboolean         gsm_app_stop            (GsmApp     *app,
+                                          GError    **error);
+const char      *gsm_app_get_id          (GsmApp     *app);
+const char      *gsm_app_get_client_id   (GsmApp     *app);
 GsmManagerPhase  gsm_app_get_phase       (GsmApp     *app);
+gboolean         gsm_app_is_running      (GsmApp     *app);
+
+void             gsm_app_exited          (GsmApp     *app);
+
+
+const char      *gsm_app_get_basename    (GsmApp     *app);
 gboolean         gsm_app_provides        (GsmApp     *app,
                                           const char *service);
 gboolean         gsm_app_is_disabled     (GsmApp     *app);
-pid_t            gsm_app_launch          (GsmApp     *app,
-                                          GError    **err);
 void             gsm_app_set_client      (GsmApp     *app,
                                           GsmClient  *client);
 

Modified: branches/dbus_based/gnome-session/gsm-autostart-app.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-autostart-app.c	(original)
+++ branches/dbus_based/gnome-session/gsm-autostart-app.c	Fri Jun 13 00:14:09 2008
@@ -24,6 +24,7 @@
 
 #include <ctype.h>
 #include <string.h>
+#include <sys/wait.h>
 #include <gio/gio.h>
 
 #include "gsm-autostart-app.h"
@@ -32,6 +33,9 @@
 struct _GsmAutostartAppPrivate {
         GFileMonitor         *monitor;
         gboolean              condition;
+        EggDesktopFile       *desktop_file;
+        GPid                  pid;
+        char                 *startup_id;
 };
 
 enum {
@@ -39,13 +43,14 @@
         LAST_SIGNAL
 };
 
-static guint signals[LAST_SIGNAL] = { 0 };
+enum {
+        PROP_0,
+        PROP_DESKTOP_FILE,
+};
 
-static void     gsm_autostart_app_dispose (GObject *object);
-static gboolean is_disabled               (GsmApp *app);
+static guint signals[LAST_SIGNAL] = { 0 };
 
-#define GSM_AUTOSTART_APP_GET_PRIVATE(object)                           \
-        (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSM_TYPE_AUTOSTART_APP, GsmAutostartAppPrivate))
+#define GSM_AUTOSTART_APP_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSM_TYPE_AUTOSTART_APP, GsmAutostartAppPrivate))
 
 G_DEFINE_TYPE (GsmAutostartApp, gsm_autostart_app, GSM_TYPE_APP)
 
@@ -54,70 +59,134 @@
 {
         app->priv = GSM_AUTOSTART_APP_GET_PRIVATE (app);
 
+        app->priv->pid = -1;
         app->priv->monitor = NULL;
         app->priv->condition = FALSE;
 }
 
 static void
-gsm_autostart_app_class_init (GsmAutostartAppClass *klass)
+gsm_autostart_app_set_desktop_file (GsmAutostartApp *app,
+                                    const char      *desktop_file)
 {
-        GObjectClass *object_class = G_OBJECT_CLASS (klass);
-        GsmAppClass *app_class = GSM_APP_CLASS (klass);
+        GError *error;
+        char   *phase_str;
+        int     phase;
 
-        object_class->dispose = gsm_autostart_app_dispose;
+        if (app->priv->desktop_file != NULL) {
+                egg_desktop_file_free (app->priv->desktop_file);
+                app->priv->desktop_file = NULL;
+        }
 
-        app_class->is_disabled = is_disabled;
+        if (desktop_file == NULL) {
+                return;
+        }
 
-        signals[CONDITION_CHANGED] =
-                g_signal_new ("condition-changed",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (GsmAutostartAppClass, condition_changed),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__BOOLEAN,
-                              G_TYPE_NONE,
-                              1,
-                              G_TYPE_BOOLEAN);
+        app->priv->desktop_file = egg_desktop_file_new (desktop_file, &error);
+        if (app->priv->desktop_file == NULL) {
+                g_warning ("Could not parse desktop file %s: %s",
+                           desktop_file,
+                           error->message);
+                g_error_free (error);
+                return;
+        }
 
-        g_type_class_add_private (object_class, sizeof (GsmAutostartAppPrivate));
+        phase_str = egg_desktop_file_get_string (app->priv->desktop_file,
+                                             "X-GNOME-Autostart-Phase",
+                                             NULL);
+        if (phase_str != NULL) {
+                if (strcmp (phase_str, "Initialization") == 0) {
+                        phase = GSM_MANAGER_PHASE_INITIALIZATION;
+                } else if (strcmp (phase_str, "WindowManager") == 0) {
+                        phase = GSM_MANAGER_PHASE_WINDOW_MANAGER;
+                } else if (strcmp (phase_str, "Panel") == 0) {
+                        phase = GSM_MANAGER_PHASE_PANEL;
+                } else if (strcmp (phase_str, "Desktop") == 0) {
+                        phase = GSM_MANAGER_PHASE_DESKTOP;
+                } else {
+                        phase = GSM_MANAGER_PHASE_APPLICATION;
+                }
+
+                g_free (phase_str);
+        } else {
+                phase = GSM_MANAGER_PHASE_APPLICATION;
+        }
+
+        g_object_set (app, "phase", phase, NULL);
 }
 
 static void
-gsm_autostart_app_dispose (GObject *object)
+gsm_autostart_app_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue  *value,
+                                GParamSpec    *pspec)
 {
-        GsmAutostartAppPrivate *priv;
+        GsmAutostartApp *self;
 
-        priv = GSM_AUTOSTART_APP (object)->priv;
+        self = GSM_AUTOSTART_APP (object);
 
-        if (priv->monitor) {
-                g_file_monitor_cancel (priv->monitor);
+        switch (prop_id) {
+        case PROP_DESKTOP_FILE:
+                gsm_autostart_app_set_desktop_file (self, g_value_get_string (value));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
         }
 }
 
-GsmApp *
-gsm_autostart_app_new (const char *desktop_file,
-                       const char *client_id)
+static void
+gsm_autostart_app_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
 {
-        GsmApp *app;
+        GsmAutostartApp *self;
 
-        app = g_object_new (GSM_TYPE_AUTOSTART_APP,
-                            "desktop-file", desktop_file,
-                            "client-id", client_id,
-                            NULL);
-        if (!app->desktop_file) {
-                g_object_unref (app);
-                app = NULL;
+        self = GSM_AUTOSTART_APP (object);
+
+        switch (prop_id) {
+        case PROP_DESKTOP_FILE:
+                if (self->priv->desktop_file != NULL) {
+                        g_value_set_string (value, egg_desktop_file_get_source (self->priv->desktop_file));
+                } else {
+                        g_value_set_string (value, NULL);
+                }
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsm_autostart_app_dispose (GObject *object)
+{
+        GsmAutostartAppPrivate *priv;
+
+        priv = GSM_AUTOSTART_APP (object)->priv;
+
+        if (priv->startup_id) {
+                g_free (priv->startup_id);
+                priv->startup_id = NULL;
         }
 
-        return app;
+        if (priv->desktop_file) {
+                egg_desktop_file_free (priv->desktop_file);
+                priv->desktop_file = NULL;
+        }
+
+        if (priv->monitor) {
+                g_file_monitor_cancel (priv->monitor);
+        }
 }
 
+
 static void
-unless_exists_condition_cb (GFileMonitor *monitor,
-                            GFile *file,
-                            GFile *other_file,
-                            GFileMonitorEvent event,
-                            GsmApp *app)
+if_exists_condition_cb (GFileMonitor *monitor,
+                        GFile *file,
+                        GFile *other_file,
+                        GFileMonitorEvent event,
+                        GsmApp *app)
 {
         GsmAutostartAppPrivate *priv;
         gboolean condition = FALSE;
@@ -125,7 +194,7 @@
         priv = GSM_AUTOSTART_APP (app)->priv;
 
         switch (event) {
-        case G_FILE_MONITOR_EVENT_DELETED:
+        case G_FILE_MONITOR_EVENT_CREATED:
                 condition = TRUE;
                 break;
 
@@ -142,11 +211,11 @@
 }
 
 static void
-if_exists_condition_cb (GFileMonitor *monitor,
-                        GFile *file,
-                        GFile *other_file,
-                        GFileMonitorEvent event,
-                        GsmApp *app)
+unless_exists_condition_cb (GFileMonitor *monitor,
+                            GFile *file,
+                            GFile *other_file,
+                            GFileMonitorEvent event,
+                            GsmApp *app)
 {
         GsmAutostartAppPrivate *priv;
         gboolean condition = FALSE;
@@ -154,7 +223,7 @@
         priv = GSM_AUTOSTART_APP (app)->priv;
 
         switch (event) {
-        case G_FILE_MONITOR_EVENT_CREATED:
+        case G_FILE_MONITOR_EVENT_DELETED:
                 condition = TRUE;
                 break;
 
@@ -198,24 +267,42 @@
 }
 
 static gboolean
+is_running (GsmApp *app)
+{
+        GsmAutostartAppPrivate *priv;
+        gboolean                is;
+
+        priv = GSM_AUTOSTART_APP (app)->priv;
+
+        /* is running if pid is still valid or
+         * or a client is connected
+         */
+        /* FIXME: check client */
+        is = (priv->pid != -1);
+
+        return is;
+}
+
+static gboolean
 is_disabled (GsmApp *app)
 {
         GsmAutostartAppPrivate *priv;
-        char *condition;
-        gboolean autorestart = FALSE;
+        char                   *condition;
+        gboolean                autorestart = FALSE;
 
         priv = GSM_AUTOSTART_APP (app)->priv;
 
-        if (egg_desktop_file_has_key (app->desktop_file,
+        if (egg_desktop_file_has_key (priv->desktop_file,
                                       "X-GNOME-AutoRestart", NULL)) {
-                autorestart = egg_desktop_file_get_boolean (app->desktop_file,
-                                                            "X-GNOME-AutoRestart", NULL);
+                autorestart = egg_desktop_file_get_boolean (priv->desktop_file,
+                                                            "X-GNOME-AutoRestart",
+                                                            NULL);
         }
 
         /* X-GNOME-Autostart-enabled key, used by old gnome-session */
-        if (egg_desktop_file_has_key (app->desktop_file,
+        if (egg_desktop_file_has_key (priv->desktop_file,
                                       "X-GNOME-Autostart-enabled", NULL) &&
-            !egg_desktop_file_get_boolean (app->desktop_file,
+            !egg_desktop_file_get_boolean (priv->desktop_file,
                                            "X-GNOME-Autostart-enabled", NULL)) {
                 g_debug ("app %s is disabled by X-GNOME-Autostart-enabled",
                          gsm_app_get_basename (app));
@@ -223,7 +310,7 @@
         }
 
         /* Hidden key, used by autostart spec */
-        if (egg_desktop_file_get_boolean (app->desktop_file,
+        if (egg_desktop_file_get_boolean (priv->desktop_file,
                                           EGG_DESKTOP_FILE_KEY_HIDDEN, NULL)) {
                 g_debug ("app %s is disabled by Hidden",
                          gsm_app_get_basename (app));
@@ -231,14 +318,14 @@
         }
 
         /* Check OnlyShowIn/NotShowIn/TryExec */
-        if (!egg_desktop_file_can_launch (app->desktop_file, "GNOME")) {
+        if (!egg_desktop_file_can_launch (priv->desktop_file, "GNOME")) {
                 g_debug ("app %s not installed or not for GNOME",
                          gsm_app_get_basename (app));
                 return TRUE;
         }
 
         /* Check AutostartCondition */
-        condition = egg_desktop_file_get_string (app->desktop_file,
+        condition = egg_desktop_file_get_string (priv->desktop_file,
                                                  "AutostartCondition",
                                                  NULL);
 
@@ -340,3 +427,169 @@
 
         return FALSE;
 }
+
+static void
+app_exited (GPid    pid,
+            int     status,
+            GsmApp *app)
+{
+        if (WIFEXITED (status)) {
+                gsm_app_exited (app);
+        }
+}
+
+static gboolean
+launch (GsmApp  *app,
+        GError **error)
+{
+        char    *env[2] = { NULL, NULL };
+        gboolean success;
+        GsmAutostartApp *aapp;
+
+        aapp = GSM_AUTOSTART_APP (app);
+
+        g_return_val_if_fail (aapp->priv->desktop_file != NULL, FALSE);
+
+        if (egg_desktop_file_get_boolean (aapp->priv->desktop_file,
+                                          "X-GNOME-Autostart-Notify", NULL) ||
+            egg_desktop_file_get_boolean (aapp->priv->desktop_file,
+                                          "AutostartNotify", NULL)) {
+                env[0] = g_strdup_printf ("DESKTOP_AUTOSTART_ID=%s",
+                                          gsm_app_get_client_id (app));
+        }
+
+        success = egg_desktop_file_launch (aapp->priv->desktop_file,
+                                           NULL,
+                                           error,
+                                           EGG_DESKTOP_FILE_LAUNCH_PUTENV, env,
+                                           EGG_DESKTOP_FILE_LAUNCH_FLAGS, G_SPAWN_DO_NOT_REAP_CHILD,
+                                           EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, &aapp->priv->pid,
+                                           EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID, &aapp->priv->startup_id,
+                                           NULL);
+
+        g_free (env[0]);
+
+        if (success) {
+                /* In case the app belongs to Initialization phase, we monitor
+                 * if it exits to emit proper "exited" signal to session. */
+                if (gsm_app_get_phase (app) == GSM_MANAGER_PHASE_INITIALIZATION) {
+                        g_child_watch_add ((GPid) aapp->priv->pid,
+                                           (GChildWatchFunc)app_exited,
+                                           app);
+                }
+
+                return TRUE;
+        } else {
+                return FALSE;
+        }
+}
+
+
+static const char *
+get_basename (GsmApp *app)
+{
+        const char *location, *slash;
+
+        if (GSM_AUTOSTART_APP (app)->priv->desktop_file == NULL) {
+                return NULL;
+        }
+
+        location = egg_desktop_file_get_source (GSM_AUTOSTART_APP (app)->priv->desktop_file);
+
+        slash = strrchr (location, '/');
+        if (slash != NULL) {
+                return slash + 1;
+        } else {
+                return location;
+        }
+}
+
+static gboolean
+gsm_autostart_app_provides (GsmApp     *app,
+                            const char *service)
+{
+        char           **provides;
+        gsize            len;
+        gsize            i;
+        GsmAutostartApp *aapp;
+
+        g_return_val_if_fail (GSM_IS_APP (app), FALSE);
+
+        aapp = GSM_AUTOSTART_APP (app);
+
+        if (aapp->priv->desktop_file == NULL) {
+                return FALSE;
+        }
+
+        provides = egg_desktop_file_get_string_list (aapp->priv->desktop_file,
+                                                     "X-GNOME-Provides",
+                                                     &len, NULL);
+        if (!provides) {
+                return FALSE;
+        }
+
+        for (i = 0; i < len; i++) {
+                if (!strcmp (provides[i], service)) {
+                        g_strfreev (provides);
+                        return TRUE;
+                }
+        }
+
+        g_strfreev (provides);
+        return FALSE;
+}
+
+static void
+gsm_autostart_app_class_init (GsmAutostartAppClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GsmAppClass  *app_class = GSM_APP_CLASS (klass);
+
+        object_class->set_property = gsm_autostart_app_set_property;
+        object_class->get_property = gsm_autostart_app_get_property;
+        object_class->dispose = gsm_autostart_app_dispose;
+
+        app_class->is_disabled = is_disabled;
+        app_class->is_running = is_running;
+        app_class->start = launch;
+        app_class->provides = gsm_autostart_app_provides;
+        app_class->get_basename = get_basename;
+
+        g_object_class_install_property (object_class,
+                                         PROP_DESKTOP_FILE,
+                                         g_param_spec_string ("desktop-file",
+                                                              "Desktop file",
+                                                              "Freedesktop .desktop file",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        signals[CONDITION_CHANGED] =
+                g_signal_new ("condition-changed",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GsmAutostartAppClass, condition_changed),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__BOOLEAN,
+                              G_TYPE_NONE,
+                              1,
+                              G_TYPE_BOOLEAN);
+
+        g_type_class_add_private (object_class, sizeof (GsmAutostartAppPrivate));
+}
+
+GsmApp *
+gsm_autostart_app_new (const char *desktop_file,
+                       const char *client_id)
+{
+        GsmAutostartApp *app;
+
+        app = g_object_new (GSM_TYPE_AUTOSTART_APP,
+                            "desktop-file", desktop_file,
+                            "client-id", client_id,
+                            NULL);
+        if (app->priv->desktop_file == NULL) {
+                g_object_unref (app);
+                app = NULL;
+        }
+
+        return GSM_APP (app);
+}

Modified: branches/dbus_based/gnome-session/gsm-client-store.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client-store.c	(original)
+++ branches/dbus_based/gnome-session/gsm-client-store.c	Fri Jun 13 00:14:09 2008
@@ -169,22 +169,6 @@
         return ret;
 }
 
-static gboolean
-_has_client_id (const char *id,
-                GsmClient  *client,
-                gpointer    user_data)
-{
-        const char *sm_id_a;
-        const char *sm_id_b;
-
-        sm_id_a = user_data;
-        sm_id_b = gsm_client_get_client_id (client);
-        if (sm_id_b == NULL) {
-                return FALSE;
-        }
-        return (strcmp (sm_id_a, sm_id_b) == 0);
-}
-
 gboolean
 gsm_client_store_add (GsmClientStore *store,
                       GsmClient      *client)
@@ -211,7 +195,7 @@
         return TRUE;
 }
 
-static void
+void
 gsm_client_store_set_locked (GsmClientStore *store,
                              gboolean        locked)
 {

Modified: branches/dbus_based/gnome-session/gsm-client-store.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client-store.h	(original)
+++ branches/dbus_based/gnome-session/gsm-client-store.h	Fri Jun 13 00:14:09 2008
@@ -68,6 +68,9 @@
 
 GsmClientStore *    gsm_client_store_new                      (void);
 
+void                gsm_client_store_set_locked               (GsmClientStore    *store,
+                                                               gboolean           locked);
+
 guint               gsm_client_store_size                     (GsmClientStore    *store);
 gboolean            gsm_client_store_add                      (GsmClientStore    *store,
                                                                GsmClient         *client);

Modified: branches/dbus_based/gnome-session/gsm-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-client.c	Fri Jun 13 00:14:09 2008
@@ -116,6 +116,7 @@
         g_return_if_fail (client->priv != NULL);
 
         g_free (client->priv->id);
+        g_free (client->priv->client_id);
 }
 
 void

Modified: branches/dbus_based/gnome-session/gsm-manager.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.c	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.c	Fri Jun 13 00:14:09 2008
@@ -69,8 +69,7 @@
         GsmClientStore         *store;
 
         /* Startup/resumed apps */
-        GSList                 *apps;
-        GHashTable             *apps_by_name;
+        GHashTable             *apps_by_id;
 
         /* Current status */
         char                   *name;
@@ -163,13 +162,13 @@
 
         client = gsm_client_store_find (manager->priv->store,
                                         (GsmClientStoreFunc)_find_by_client_id,
-                                        app->client_id);
+                                        (char *)gsm_app_get_client_id (app));
 
         if (condition) {
                 GError *error = NULL;
 
-                if (app->pid <= 0 && client == NULL) {
-                        gsm_app_launch (app, &error);
+                if (!gsm_app_is_running (app) && client == NULL) {
+                        gsm_app_start (app, &error);
                 }
 
                 if (error != NULL) {
@@ -188,7 +187,7 @@
                  */
 
                 gsm_client_stop (client);
-                app->pid = -1;
+                gsm_app_stop (app, NULL);
         }
 }
 
@@ -249,62 +248,72 @@
 }
 
 static void
-start_phase (GsmManager *manager)
+_start_app (const char *id,
+            GsmApp     *app,
+            GsmManager *manager)
 {
-        GsmApp *app;
-        GSList *a;
-        GError *err = NULL;
+        GError  *error;
+        gboolean res;
 
-        g_debug ("starting phase %d\n", manager->priv->phase);
+        if (gsm_app_get_phase (app) != manager->priv->phase) {
+                return;
+        }
 
-        g_slist_free (manager->priv->pending_apps);
-        manager->priv->pending_apps = NULL;
+        /* Keep track of app autostart condition in order to react
+         * accordingly in the future. */
+        g_signal_connect (app,
+                          "condition-changed",
+                          G_CALLBACK (app_condition_changed),
+                          manager);
 
-        for (a = manager->priv->apps; a; a = a->next) {
-                app = a->data;
+        if (gsm_app_is_disabled (app)) {
+                return;
+        }
 
-                if (gsm_app_get_phase (app) != manager->priv->phase) {
-                        continue;
+        error = NULL;
+        res = gsm_app_start (app, &error);
+        if (!res) {
+                if (error != NULL) {
+                        g_warning ("Could not launch application '%s': %s",
+                                   gsm_app_get_basename (app),
+                                   error->message);
+                        g_error_free (error);
+                        error = NULL;
                 }
+                return;
+        }
 
-                /* Keep track of app autostart condition in order to react
-                 * accordingly in the future. */
+        if (manager->priv->phase == GSM_MANAGER_PHASE_INITIALIZATION) {
+                /* Applications from Initialization phase are considered
+                 * registered when they exit normally. This is because
+                 * they are expected to just do "something" and exit */
                 g_signal_connect (app,
-                                  "condition-changed",
-                                  G_CALLBACK (app_condition_changed),
+                                  "exited",
+                                  G_CALLBACK (app_registered),
                                   manager);
+        }
 
-                if (gsm_app_is_disabled (app)) {
-                        continue;
-                }
+        if (manager->priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
+                g_signal_connect (app,
+                                  "registered",
+                                  G_CALLBACK (app_registered),
+                                  manager);
+                manager->priv->pending_apps = g_slist_prepend (manager->priv->pending_apps, app);
+        }
+}
 
-                if (gsm_app_launch (app, &err) > 0) {
-                        if (manager->priv->phase == GSM_MANAGER_PHASE_INITIALIZATION) {
-                                /* Applications from Initialization phase are considered
-                                 * registered when they exit normally. This is because
-                                 * they are expected to just do "something" and exit */
-                                g_signal_connect (app,
-                                                  "exited",
-                                                  G_CALLBACK (app_registered),
-                                                  manager);
-                        }
+static void
+start_phase (GsmManager *manager)
+{
 
-                        if (manager->priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
-                                g_signal_connect (app,
-                                                  "registered",
-                                                  G_CALLBACK (app_registered),
-                                                  manager);
+        g_debug ("starting phase %d\n", manager->priv->phase);
 
-                                manager->priv->pending_apps = g_slist_prepend (manager->priv->pending_apps, app);
-                        }
-                } else if (err != NULL) {
-                        g_warning ("Could not launch application '%s': %s",
-                                   gsm_app_get_basename (app),
-                                   err->message);
-                        g_error_free (err);
-                        err = NULL;
-                }
-        }
+        g_slist_free (manager->priv->pending_apps);
+        manager->priv->pending_apps = NULL;
+
+        g_hash_table_foreach (manager->priv->apps_by_id,
+                              (GHFunc)_start_app,
+                              manager);
 
         if (manager->priv->pending_apps != NULL) {
                 if (manager->priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
@@ -506,24 +515,23 @@
 append_app (GsmManager *manager,
             GsmApp     *app)
 {
-        const char *basename;
+        const char *id;
         GsmApp     *dup;
 
-        basename = gsm_app_get_basename (app);
-        if (basename == NULL) {
+        id = gsm_app_get_id (app);
+        if (id == NULL) {
                 g_object_unref (app);
                 return;
         }
 
-        dup = g_hash_table_lookup (manager->priv->apps_by_name, basename);
+        dup = g_hash_table_lookup (manager->priv->apps_by_id, id);
         if (dup != NULL) {
                 /* FIXME */
                 g_object_unref (app);
                 return;
         }
 
-        manager->priv->apps = g_slist_append (manager->priv->apps, app);
-        g_hash_table_insert (manager->priv->apps_by_name, g_strdup (basename), app);
+        g_hash_table_insert (manager->priv->apps_by_id, g_strdup (id), app);
 }
 
 static void
@@ -691,13 +699,20 @@
         g_free (session_filename);
 }
 
+static gboolean
+_find_app_provides (const char *id,
+                    GsmApp     *app,
+                    const char *service)
+{
+        return gsm_app_provides (app, service);
+}
+
 static void
 append_required_apps (GsmManager *manager)
 {
         GSList      *required_components;
         GSList      *r;
         GsmApp      *app;
-        gboolean     found;
         GConfClient *client;
 
         client = gconf_client_get_default ();
@@ -707,7 +722,6 @@
         g_object_unref (client);
 
         for (r = required_components; r; r = r->next) {
-                GSList     *a;
                 GConfEntry *entry;
                 const char *default_provider;
                 const char *service;
@@ -725,23 +739,18 @@
                         continue;
                 }
 
-                for (a = manager->priv->apps, found = FALSE; a; a = a->next) {
-                        app = a->data;
-
-                        if (gsm_app_provides (app, service)) {
-                                found = TRUE;
-                                break;
-                        }
-                }
-
-                if (!found) {
+                app = g_hash_table_find (manager->priv->apps_by_id,
+                                         (GHRFunc)_find_app_provides,
+                                         (char *)service);
+                if (app == NULL) {
                         char *client_id;
 
                         client_id = gsm_util_generate_client_id ();
                         app = gsm_autostart_app_new (default_provider, client_id);
                         g_free (client_id);
-                        if (app)
+                        if (app != NULL) {
                                 append_app (manager, app);
+                        }
                         /* FIXME: else error */
                 }
 
@@ -883,7 +892,10 @@
 
         manager->priv = GSM_MANAGER_GET_PRIVATE (manager);
 
-        manager->priv->apps_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+        manager->priv->apps_by_id = g_hash_table_new_full (g_str_hash,
+                                                           g_str_equal,
+                                                           g_free,
+                                                           g_object_unref);
 
         manager->priv->logout_response_id = GTK_RESPONSE_NONE;
 }
@@ -904,6 +916,8 @@
                 g_object_unref (manager->priv->store);
         }
 
+        g_free (manager->priv->name);
+
         /* FIXME */
 
         G_OBJECT_CLASS (gsm_manager_parent_class)->finalize (object);
@@ -1024,6 +1038,9 @@
 {
         manager->priv->phase = GSM_MANAGER_PHASE_SHUTDOWN;
 
+        /* lock the client store so no clients may be added */
+        gsm_client_store_set_locked (manager->priv->store, TRUE);
+
         if (gsm_client_store_size (manager->priv->store) == 0) {
                 manager_shutdown (manager);
         }

Modified: branches/dbus_based/gnome-session/gsm-resumed-app.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-resumed-app.c	(original)
+++ branches/dbus_based/gnome-session/gsm-resumed-app.c	Fri Jun 13 00:14:09 2008
@@ -26,8 +26,13 @@
 
 #include "gsm-resumed-app.h"
 
-static const char *get_basename (GsmApp *app);
-static pid_t       launch       (GsmApp *app, GError **error);
+struct _GsmResumedAppPrivate
+{
+        char    *program;
+        char    *restart_command;
+        char    *discard_command;
+        gboolean discard_on_resume;
+};
 
 G_DEFINE_TYPE (GsmResumedApp, gsm_resumed_app, GSM_TYPE_APP)
 
@@ -37,13 +42,62 @@
         ;
 }
 
+static gboolean
+launch (GsmApp  *app,
+        GError **err)
+{
+        const char *restart_command;
+        int         argc;
+        char      **argv;
+        gboolean    success;
+        gboolean    res;
+        pid_t       pid;
+
+        restart_command = GSM_RESUMED_APP (app)->priv->restart_command;
+
+        if (restart_command == NULL) {
+                return FALSE;
+        }
+
+        res = g_shell_parse_argv (restart_command, &argc, &argv, err);
+        if (!res) {
+                return FALSE;
+        }
+
+        /* In theory, we should set up the environment according to
+         * SmEnvironment, and the current directory according to
+         * SmCurrentDirectory. However, ksmserver doesn't support either of
+         * those properties, so apps that want to be portable can't depend
+         * on them working anyway. Also, no one ever uses them. So we just
+         * ignore them.
+         */
+
+        success = g_spawn_async (NULL,
+                                 argv,
+                                 NULL,
+                                 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+                                 NULL,
+                                 NULL,
+                                 &pid,
+                                 err);
+        g_strfreev (argv);
+
+        return success;
+}
+
+static const char *
+get_basename (GsmApp *app)
+{
+        return GSM_RESUMED_APP (app)->priv->program;
+}
+
 static void
 gsm_resumed_app_class_init (GsmResumedAppClass *klass)
 {
         GsmAppClass *app_class = GSM_APP_CLASS (klass);
 
         app_class->get_basename = get_basename;
-        app_class->launch = launch;
+        app_class->start = launch;
 }
 
 /**
@@ -59,10 +113,13 @@
  * @session_file is not actually a saved XSMP client.
  **/
 GsmApp *
-gsm_resumed_app_new_from_legacy_session (GKeyFile *session_file, int n)
+gsm_resumed_app_new_from_legacy_session (GKeyFile *session_file,
+                                         int       n)
 {
         GsmResumedApp *app;
-        char *key, *id, *val;
+        char          *key;
+        char          *id;
+        char          *val;
 
         key = g_strdup_printf ("%d,id", n);
         id = g_key_file_get_string (session_file, "Default", key, NULL);
@@ -84,7 +141,7 @@
         g_free (key);
 
         if (val) {
-                app->program = val;
+                app->priv->program = val;
         }
 
         key = g_strdup_printf ("%d," SmRestartCommand, n);
@@ -92,114 +149,14 @@
         g_free (key);
 
         if (val) {
-                app->restart_command = val;
+                app->priv->restart_command = val;
         }
 
         /* We ignore the discard_command on apps resumed from the legacy
          * session, so that the legacy session will still work if the user
          * reverts back to the old gnome-session.
          */
-        app->discard_on_resume = FALSE;
+        app->priv->discard_on_resume = FALSE;
 
         return (GsmApp *) app;
 }
-
-/**
- * gsm_resumed_app_new_from_session:
- * @session_file: a session file
- * @group: the group containing the client to read
- * @discard: whether or not the app's state should be discarded after
- * it resumes.
- *
- * Creates a new #GsmApp corresponding to the indicated client in a
- * session file.
- *
- * Return value: the new #GsmApp, or %NULL on error
- **/
-#if 0
-GsmApp *
-gsm_resumed_app_new_from_session (GKeyFile *session_file, const char *group,
-                                  gboolean discard)
-{
-        GsmResumedApp *app;
-        char *desktop_file, *client_id, *val;
-
-        desktop_file = g_key_file_get_string (session_file, group,
-                                              "_GSM_DesktopFile", NULL);
-        client_id = g_key_file_get_string (session_file, group, "id", NULL);
-
-        app = g_object_new (GSM_TYPE_RESUMED_APP,
-                            "desktop-file", desktop_file,
-                            "client-id", client_id,
-                            NULL);
-        g_free (desktop_file);
-        g_free (client_id);
-
-        /* Replace Exec key with RestartCommand */
-        val = g_key_file_get_string (session_file, group,
-                                     SmRestartCommand, NULL);
-        gsm_app_set_exec (app, val);
-        g_free (val);
-
-        /* Use Program for the name if there's no localized name */
-        if (!gsm_app_get_name (app)) {
-                val = g_key_file_get_string (session_file, group,
-                                             SmProgram, NULL);
-                gsm_app_set_name (app, val);
-                g_free (val);
-        }
-
-        app->discard_command = g_key_file_get_string (session_file, group,
-                                                      SmDiscardCommand, NULL);
-        app->discard_on_resume = discard;
-
-        /* FIXME: if discard_on_resume is set, then the app needs to find
-         * out if it has been matched up with a GsmClient, so it can run its
-         * discard command later. (It can't actually run the discard command
-         * right away when the client connects, because the client might not
-         * have actually read in its old state at that point. So it's
-         * probably best to not run the discard command until after the
-         * client quits.
-         */
-        return (GsmApp *)app;
-}
-#endif
-
-static const char *
-get_basename (GsmApp *app)
-{
-        return GSM_RESUMED_APP (app)->program;
-}
-
-static pid_t
-launch (GsmApp *app, GError **err)
-{
-        const char *restart_command = GSM_RESUMED_APP (app)->restart_command;
-        int argc;
-        char **argv;
-        gboolean success;
-        pid_t pid;
-
-        if (!restart_command) {
-                return (pid_t)-1;
-        }
-
-        if (!g_shell_parse_argv (restart_command, &argc, &argv, err)) {
-                return (pid_t)-1;
-        }
-
-        /* In theory, we should set up the environment according to
-         * SmEnvironment, and the current directory according to
-         * SmCurrentDirectory. However, ksmserver doesn't support either of
-         * those properties, so apps that want to be portable can't depend
-         * on them working anyway. Also, no one ever uses them. So we just
-         * ignore them.
-         */
-
-        success = g_spawn_async (NULL, argv, NULL,
-                                 G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-                                 NULL, NULL, &pid, err);
-        g_strfreev (argv);
-
-        return success ? pid : (pid_t)-1;
-}

Modified: branches/dbus_based/gnome-session/gsm-resumed-app.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-resumed-app.h	(original)
+++ branches/dbus_based/gnome-session/gsm-resumed-app.h	Fri Jun 13 00:14:09 2008
@@ -38,12 +38,8 @@
 
 struct _GsmResumedApp
 {
-        GsmApp   parent;
-
-        char    *program;
-        char    *restart_command;
-        char    *discard_command;
-        gboolean discard_on_resume;
+        GsmApp                parent;
+        GsmResumedAppPrivate *priv;
 };
 
 struct _GsmResumedAppClass

Modified: branches/dbus_based/gnome-session/gsm-xsmp-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-xsmp-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-client.c	Fri Jun 13 00:14:09 2008
@@ -48,7 +48,6 @@
 
         int        current_save_yourself;
         int        next_save_yourself;
-        char      *id;
         char      *description;
         GPtrArray *props;
 };
@@ -562,20 +561,22 @@
 
         g_debug ("xsmp_finalize (%s)", client->priv->description);
 
-        if (client->priv->watch_id) {
+        if (client->priv->watch_id > 0) {
                 g_source_remove (client->priv->watch_id);
         }
 
-        if (client->priv->conn) {
+        if (client->priv->conn != NULL) {
                 SmsCleanUp (client->priv->conn);
         } else {
                 IceCloseConnection (client->priv->ice_connection);
         }
 
-        if (client->priv->protocol_timeout) {
+        if (client->priv->protocol_timeout > 0) {
                 g_source_remove (client->priv->protocol_timeout);
         }
 
+        g_free (client->priv->description);
+
         G_OBJECT_CLASS (gsm_xsmp_client_parent_class)->finalize (object);
 }
 



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