[gnome-session] save: make sure app state is written into desktop file



commit f7ff80775abd345a33e8a656ba019bc05e39d7bb
Author: Ray Strode <rstrode redhat com>
Date:   Mon Nov 27 15:40:54 2017 -0500

    save: make sure app state is written into desktop file
    
    There are a number of important bits of app state written into
    an applications desktop file that needs to be restored when
    the session is saved.  For instance, the phase in which the client
    should get started.
    
    That state is currently stored on the GsmApp object, which is
    inaccessible, from the client save function.
    
    This commit adds the neccesary plumbing to route the GsmApp object
    associated with a client to the client save function, and also
    adds code to allow the app object to augment the client keyfile at
    save time.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=790913

 gnome-session/gsm-app.c           |    9 +++++
 gnome-session/gsm-app.h           |    8 ++++
 gnome-session/gsm-autostart-app.c |   70 +++++++++++++++++++++++++++++++++++++
 gnome-session/gsm-client.c        |    3 +-
 gnome-session/gsm-client.h        |    3 ++
 gnome-session/gsm-dbus-client.c   |    1 +
 gnome-session/gsm-manager.c       |    2 +-
 gnome-session/gsm-session-save.c  |   20 ++++++++++-
 gnome-session/gsm-session-save.h  |    1 +
 gnome-session/gsm-xsmp-client.c   |    9 +++++
 10 files changed, 123 insertions(+), 3 deletions(-)
---
diff --git a/gnome-session/gsm-app.c b/gnome-session/gsm-app.c
index 845e067..d1ef89a 100644
--- a/gnome-session/gsm-app.c
+++ b/gnome-session/gsm-app.c
@@ -558,3 +558,12 @@ gsm_app_set_registered (GsmApp   *app,
                 g_object_notify (G_OBJECT (app), "registered");
         }
 }
+
+gboolean
+gsm_app_save_to_keyfile (GsmApp    *app,
+                         GKeyFile  *keyfile,
+                         GError   **error)
+{
+        g_debug ("Saving app: %s", app->priv->id);
+        return GSM_APP_GET_CLASS (app)->impl_save_to_keyfile (app, keyfile, error);
+}
diff --git a/gnome-session/gsm-app.h b/gnome-session/gsm-app.h
index 14a9f94..f38b3be 100644
--- a/gnome-session/gsm-app.h
+++ b/gnome-session/gsm-app.h
@@ -74,6 +74,10 @@ struct _GsmAppClass
         const char *(*impl_get_app_id)                (GsmApp     *app);
         gboolean    (*impl_is_disabled)               (GsmApp     *app);
         gboolean    (*impl_is_conditionally_disabled) (GsmApp     *app);
+
+        gboolean    (*impl_save_to_keyfile)           (GsmApp     *app,
+                                                       GKeyFile   *keyfile,
+                                                       GError    **error);
 };
 
 typedef enum
@@ -121,6 +125,10 @@ gboolean         gsm_app_get_registered                 (GsmApp     *app);
 void             gsm_app_set_registered                 (GsmApp     *app,
                                                          gboolean  registered);
 
+gboolean         gsm_app_save_to_keyfile                (GsmApp    *app,
+                                                         GKeyFile  *keyfile,
+                                                         GError   **error);
+
 G_END_DECLS
 
 #endif /* __GSM_APP_H__ */
diff --git a/gnome-session/gsm-autostart-app.c b/gnome-session/gsm-autostart-app.c
index e8b390b..d946855 100644
--- a/gnome-session/gsm-autostart-app.c
+++ b/gnome-session/gsm-autostart-app.c
@@ -1341,6 +1341,75 @@ gsm_autostart_app_initable_init (GInitable *initable,
         return TRUE;
 }
 
+static gboolean
+gsm_autostart_app_save_to_keyfile (GsmApp    *base_app,
+                                   GKeyFile  *keyfile,
+                                   GError   **error)
+{
+        GsmAutostartApp *app = GSM_AUTOSTART_APP (base_app);
+        char   **provides = NULL;
+        char    *dbus_name;
+        char    *phase;
+        gboolean res;
+
+        provides = gsm_app_get_provides (base_app);
+        if (provides != NULL) {
+                g_key_file_set_string_list (keyfile,
+                                            G_KEY_FILE_DESKTOP_GROUP,
+                                            GSM_AUTOSTART_APP_PROVIDES_KEY,
+                                            (const char * const *)
+                                            provides,
+                                            g_strv_length (provides));
+                g_strfreev (provides);
+        }
+
+        phase = g_desktop_app_info_get_string (app->priv->app_info,
+                                                   GSM_AUTOSTART_APP_PHASE_KEY);
+        if (phase != NULL) {
+                g_key_file_set_string (keyfile,
+                                       G_KEY_FILE_DESKTOP_GROUP,
+                                       GSM_AUTOSTART_APP_PHASE_KEY,
+                                       phase);
+                g_free (phase);
+        }
+
+        dbus_name = g_desktop_app_info_get_string (app->priv->app_info,
+                                                   GSM_AUTOSTART_APP_DBUS_NAME_KEY);
+        if (dbus_name != NULL) {
+                g_key_file_set_string (keyfile,
+                                       G_KEY_FILE_DESKTOP_GROUP,
+                                       GSM_AUTOSTART_APP_DBUS_NAME_KEY,
+                                       dbus_name);
+                g_free (dbus_name);
+        }
+
+        res = g_desktop_app_info_has_key (app->priv->app_info,
+                                          GSM_AUTOSTART_APP_AUTORESTART_KEY);
+        if (res) {
+                g_key_file_set_boolean (keyfile,
+                                        G_KEY_FILE_DESKTOP_GROUP,
+                                        GSM_AUTOSTART_APP_AUTORESTART_KEY,
+                                        g_desktop_app_info_get_boolean (app->priv->app_info,
+                                                                        GSM_AUTOSTART_APP_AUTORESTART_KEY));
+        }
+
+        res = g_desktop_app_info_has_key (app->priv->app_info,
+                                          GSM_AUTOSTART_APP_AUTORESTART_KEY);
+        if (res) {
+                char *autostart_condition;
+
+                autostart_condition = g_desktop_app_info_get_string (app->priv->app_info, 
"AutostartCondition");
+
+                g_key_file_set_string (keyfile,
+                                       G_KEY_FILE_DESKTOP_GROUP,
+                                       "AutostartCondition",
+                                       autostart_condition);
+                g_free (autostart_condition);
+        }
+
+        return TRUE;
+}
+
 static void
 gsm_autostart_app_initable_iface_init (GInitableIface  *iface)
 {
@@ -1368,6 +1437,7 @@ gsm_autostart_app_class_init (GsmAutostartAppClass *klass)
         app_class->impl_has_autostart_condition = gsm_autostart_app_has_autostart_condition;
         app_class->impl_get_app_id = gsm_autostart_app_get_app_id;
         app_class->impl_get_autorestart = gsm_autostart_app_get_autorestart;
+        app_class->impl_save_to_keyfile = gsm_autostart_app_save_to_keyfile;
 
         g_object_class_install_property (object_class,
                                          PROP_DESKTOP_FILENAME,
diff --git a/gnome-session/gsm-client.c b/gnome-session/gsm-client.c
index 75edbbf..6828ad4 100644
--- a/gnome-session/gsm-client.c
+++ b/gnome-session/gsm-client.c
@@ -543,11 +543,12 @@ gsm_client_disconnected (GsmClient *client)
 
 GKeyFile *
 gsm_client_save (GsmClient *client,
+                 GsmApp    *app,
                  GError   **error)
 {
         g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
 
-        return GSM_CLIENT_GET_CLASS (client)->impl_save (client, error);
+        return GSM_CLIENT_GET_CLASS (client)->impl_save (client, app, error);
 }
 
 void
diff --git a/gnome-session/gsm-client.h b/gnome-session/gsm-client.h
index cd7c06d..78cb15d 100644
--- a/gnome-session/gsm-client.h
+++ b/gnome-session/gsm-client.h
@@ -33,6 +33,7 @@ G_BEGIN_DECLS
 #define GSM_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_CLIENT))
 #define GSM_CLIENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_CLIENT, GsmClientClass))
 
+typedef struct _GsmApp           GsmApp;
 typedef struct _GsmClient        GsmClient;
 typedef struct _GsmClientClass   GsmClientClass;
 
@@ -91,6 +92,7 @@ struct _GsmClientClass
         gboolean              (*impl_stop)                   (GsmClient *client,
                                                               GError   **error);
         GKeyFile *            (*impl_save)                   (GsmClient *client,
+                                                              GsmApp    *app,
                                                               GError   **error);
 };
 
@@ -133,6 +135,7 @@ gboolean              gsm_client_cancel_end_session         (GsmClient  *client,
 void                  gsm_client_disconnected               (GsmClient  *client);
 
 GKeyFile             *gsm_client_save                       (GsmClient  *client,
+                                                             GsmApp     *app,
                                                              GError    **error);
 
 gboolean              gsm_client_stop                       (GsmClient  *client,
diff --git a/gnome-session/gsm-dbus-client.c b/gnome-session/gsm-dbus-client.c
index dcf96f0..6e9b002 100644
--- a/gnome-session/gsm-dbus-client.c
+++ b/gnome-session/gsm-dbus-client.c
@@ -329,6 +329,7 @@ gsm_dbus_client_finalize (GObject *object)
 
 static GKeyFile *
 dbus_client_save (GsmClient *client,
+                  GsmApp    *app,
                   GError   **error)
 {
         g_debug ("GsmDBusClient: saving client with id %s",
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index bdba38e..cd8bb2d 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -1860,7 +1860,7 @@ maybe_save_session (GsmManager *manager)
         }
 
         error = NULL;
-        gsm_session_save (manager->priv->clients, &error);
+        gsm_session_save (manager->priv->clients, manager->priv->apps, &error);
 
         if (error) {
                 g_warning ("Error saving session: %s", error->message);
diff --git a/gnome-session/gsm-session-save.c b/gnome-session/gsm-session-save.c
index d6000e0..5272d24 100644
--- a/gnome-session/gsm-session-save.c
+++ b/gnome-session/gsm-session-save.c
@@ -22,6 +22,7 @@
 #include <glib/gstdio.h>
 #include <gio/gio.h>
 
+#include "gsm-app.h"
 #include "gsm-util.h"
 #include "gsm-autostart-app.h"
 #include "gsm-client.h"
@@ -38,16 +39,29 @@ static gboolean gsm_session_clear_saved_session (const char *directory,
 typedef struct {
         const char  *dir;
         GHashTable  *discard_hash;
+        GsmStore    *app_store;
         GError     **error;
 } SessionSaveData;
 
 static gboolean
+_app_has_app_id (const char   *id,
+                 GsmApp       *app,
+                 const char   *app_id_a)
+{
+        const char *app_id_b;
+
+        app_id_b = gsm_app_peek_app_id (app);
+        return g_strcmp0 (app_id_a, app_id_b) == 0;
+}
+
+static gboolean
 save_one_client (char            *id,
                  GObject         *object,
                  SessionSaveData *data)
 {
         GsmClient  *client;
         GKeyFile   *keyfile;
+        GsmApp     *app;
         const char *app_id;
         char       *path = NULL;
         char       *filename = NULL;
@@ -60,7 +74,10 @@ save_one_client (char            *id,
 
         local_error = NULL;
 
-        keyfile = gsm_client_save (client, &local_error);
+        app = (GsmApp *)gsm_store_find (data->app_store,
+                                        (GsmStoreFunc)_app_has_app_id,
+                                        (char *)app_id);
+        keyfile = gsm_client_save (client, app, &local_error);
 
         if (keyfile == NULL || local_error) {
                 goto out;
@@ -135,6 +152,7 @@ out:
 
 void
 gsm_session_save (GsmStore  *client_store,
+                  GsmStore  *app_store,
                   GError   **error)
 {
         GSettings       *settings;
diff --git a/gnome-session/gsm-session-save.h b/gnome-session/gsm-session-save.h
index e623260..f55c9c1 100644
--- a/gnome-session/gsm-session-save.h
+++ b/gnome-session/gsm-session-save.h
@@ -25,6 +25,7 @@
 G_BEGIN_DECLS
 
 void      gsm_session_save                 (GsmStore  *client_store,
+                                            GsmStore  *app_store,
                                             GError   **error);
 void      gsm_session_save_clear           (void);
 
diff --git a/gnome-session/gsm-xsmp-client.c b/gnome-session/gsm-xsmp-client.c
index 9358f94..8a30926 100644
--- a/gnome-session/gsm-xsmp-client.c
+++ b/gnome-session/gsm-xsmp-client.c
@@ -614,6 +614,7 @@ xsmp_get_restart_style_hint (GsmClient *client);
 
 static GKeyFile *
 xsmp_save (GsmClient *client,
+           GsmApp    *app,
            GError   **error)
 {
         GsmClientRestartStyle restart_style;
@@ -672,6 +673,14 @@ xsmp_save (GsmClient *client,
                                        GSM_AUTOSTART_APP_DISCARD_KEY,
                                        exec_discard);
 
+        if (app != NULL) {
+                gsm_app_save_to_keyfile (app, keyfile, &local_error);
+
+                if (local_error) {
+                        goto out;
+                }
+        }
+
 out:
         g_free (desktop_file_path);
         g_free (exec_program);


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