gnome-session r5355 - in trunk: . gnome-session
- From: vuntz svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r5355 - in trunk: . gnome-session
- Date: Tue, 24 Mar 2009 22:51:44 +0000 (UTC)
Author: vuntz
Date: Tue Mar 24 22:51:44 2009
New Revision: 5355
URL: http://svn.gnome.org/viewvc/gnome-session?rev=5355&view=rev
Log:
2009-03-24 Vincent Untz <vuntz gnome org>
Rework deeply the code that writes the saved session to desktop files:
we now properly discard a client when removing it; we also make sure we
save the current session before we completely remove the previously
saved session (to be on the safe side).
Note that we only discard a client when the new saved session doesn't
use the same discard command: for example, when metacity saves its
state, it will reuse the same discard command and so we can't discard
the old metacity client (it would discard the new client).
* gnome-session/gsm-util.[ch]: (gsm_util_get_empty_tmp_session_dir):
new function to get a temporary directory where to save the new
session, while we still keep the previously saved session. It also
makes sure the directory is empty.
* gnome-session/gsm-session-save.[ch]: (save_one_client): update to
make sure we remember the discard command from the client.
(gsm_session_save): rework to first save the session in the temporary
directory (and remember the discard commands from the saved clients),
and then clear the old session. We finish by renaming the temporary
directory to its final name.
(gsm_session_clear_one_client): new, to properly clear one client from
a saved session. We unlink the desktop file, but also run the discard
command if it's not used by any other client from the newly saved
session.
(gsm_session_clear_saved_session): change to clear a saved session in a
specified directory, and use gsm_session_clear_one_client() instead of
just unlinking the desktop file. Also add missing g_dir_close().
Modified:
trunk/ChangeLog
trunk/gnome-session/gsm-session-save.c
trunk/gnome-session/gsm-session-save.h
trunk/gnome-session/gsm-util.c
trunk/gnome-session/gsm-util.h
Modified: trunk/gnome-session/gsm-session-save.c
==============================================================================
--- trunk/gnome-session/gsm-session-save.c (original)
+++ trunk/gnome-session/gsm-session-save.c Tue Mar 24 22:51:44 2009
@@ -28,18 +28,27 @@
#include "gsm-session-save.h"
+static gboolean gsm_session_clear_saved_session (const char *directory,
+ GHashTable *discard_hash);
+
+typedef struct {
+ char *dir;
+ GHashTable *discard_hash;
+ GError **error;
+} SessionSaveData;
+
static gboolean
-save_one_client (char *id,
- GObject *object,
- GError **error)
+save_one_client (char *id,
+ GObject *object,
+ SessionSaveData *data)
{
GsmClient *client;
GKeyFile *keyfile;
char *path = NULL;
char *filename = NULL;
char *contents = NULL;
- const char *saved_session_dir;
gsize length = 0;
+ char *discard_exec;
GError *local_error;
client = GSM_CLIENT (object);
@@ -58,16 +67,10 @@
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);
+ path = g_build_filename (data->dir, filename, NULL);
g_file_set_contents (path,
contents,
@@ -78,6 +81,15 @@
goto out;
}
+ discard_exec = g_key_file_get_string (keyfile,
+ G_KEY_FILE_DESKTOP_GROUP,
+ "X-GNOME-Autostart-discard-exec",
+ NULL);
+ if (discard_exec) {
+ g_hash_table_insert (data->discard_hash,
+ discard_exec, discard_exec);
+ }
+
g_debug ("GsmSessionSave: saved client %s to %s", id, filename);
out:
@@ -91,7 +103,7 @@
/* in case of any error, stop saving session */
if (local_error) {
- g_propagate_error (error, local_error);
+ g_propagate_error (data->error, local_error);
g_error_free (local_error);
return TRUE;
@@ -104,39 +116,121 @@
gsm_session_save (GsmStore *client_store,
GError **error)
{
- gsm_session_clear_saved_session ();
+ const char *save_dir;
+ char *tmp_dir;
+ SessionSaveData data;
g_debug ("GsmSessionSave: Saving session");
+ save_dir = gsm_util_get_saved_session_dir ();
+ if (save_dir == NULL) {
+ g_warning ("GsmSessionSave: cannot create saved session directory");
+ return;
+ }
+
+ tmp_dir = gsm_util_get_empty_tmp_session_dir ();
+ if (tmp_dir == NULL) {
+ g_warning ("GsmSessionSave: cannot create new saved session directory");
+ return;
+ }
+
+ /* save the session in a temp directory, and remember the discard
+ * commands */
+ data.dir = tmp_dir;
+ data.discard_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ data.error = error;
+
gsm_store_foreach (client_store,
(GsmStoreFunc) save_one_client,
- error);
+ &data);
- if (*error) {
+ if (!*error) {
+ /* remove the old saved session */
+ gsm_session_clear_saved_session (save_dir, data.discard_hash);
+
+ /* rename the temp session dir */
+ if (g_file_test (save_dir, G_FILE_TEST_IS_DIR))
+ g_rmdir (save_dir);
+ g_rename (tmp_dir, save_dir);
+ } else {
g_warning ("GsmSessionSave: error saving session: %s", (*error)->message);
- gsm_session_clear_saved_session ();
+ /* FIXME: we should create a hash table filled with the discard
+ * commands that are in desktop files from save_dir. */
+ gsm_session_clear_saved_session (tmp_dir, NULL);
+ g_rmdir (tmp_dir);
+ }
+
+ g_hash_table_destroy (data.discard_hash);
+ g_free (tmp_dir);
+}
+
+static gboolean
+gsm_session_clear_one_client (const char *filename,
+ GHashTable *discard_hash)
+{
+ gboolean result = TRUE;
+ GKeyFile *key_file = NULL;
+ char *discard_exec = NULL;
+
+ g_debug ("GsmSessionSave: removing '%s' from saved session", filename);
+
+ key_file = g_key_file_new ();
+ if (g_key_file_load_from_file (key_file, filename,
+ G_KEY_FILE_NONE, NULL)) {
+ char **argv;
+ int argc;
+
+ discard_exec = g_key_file_get_string (key_file,
+ G_KEY_FILE_DESKTOP_GROUP,
+ "X-GNOME-Autostart-discard-exec",
+ NULL);
+ if (!discard_exec)
+ goto out;
+
+ if (g_hash_table_lookup (discard_hash, discard_exec))
+ goto out;
+
+ if (!g_shell_parse_argv (discard_exec, &argc, &argv, NULL))
+ goto out;
+
+ result = g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
+ NULL, NULL, NULL, NULL) && result;
+
+ g_strfreev (argv);
+ } else {
+ result = FALSE;
}
+
+out:
+ if (key_file)
+ g_key_file_free (key_file);
+ if (discard_exec)
+ g_free (discard_exec);
+
+ result = (g_unlink (filename) == 0) && result;
+
+ return result;
}
-gboolean
-gsm_session_clear_saved_session ()
+static gboolean
+gsm_session_clear_saved_session (const char *directory,
+ GHashTable *discard_hash)
{
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",
+ directory);
- g_debug ("GsmSessionSave: clearing currectly saved session at %s", saved_session_dir);
-
- if (saved_session_dir == NULL) {
+ if (directory == NULL) {
return FALSE;
}
error = NULL;
- dir = g_dir_open (saved_session_dir, 0, &error);
+ dir = g_dir_open (directory, 0, &error);
if (error) {
g_warning ("GsmSessionSave: error loading saved session directory: %s", error->message);
g_error_free (error);
@@ -144,15 +238,16 @@
}
while ((filename = g_dir_read_name (dir))) {
- char *path = g_build_filename (saved_session_dir,
+ char *path = g_build_filename (directory,
filename, NULL);
- g_debug ("GsmSessionSave: removing '%s' from saved session", path);
-
- result = result && (g_unlink (path) == 0);
+ result = gsm_session_clear_one_client (path, discard_hash)
+ && result;
g_free (path);
}
+ g_dir_close (dir);
+
return result;
}
Modified: trunk/gnome-session/gsm-session-save.h
==============================================================================
--- trunk/gnome-session/gsm-session-save.h (original)
+++ trunk/gnome-session/gsm-session-save.h Tue Mar 24 22:51:44 2009
@@ -29,8 +29,6 @@
void gsm_session_save (GsmStore *client_store,
GError **error);
-gboolean gsm_session_clear_saved_session (void);
-
G_END_DECLS
#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 Mar 24 22:51:44 2009
@@ -139,6 +139,42 @@
return FALSE;
}
+gchar *
+gsm_util_get_empty_tmp_session_dir (void)
+{
+ char *tmp;
+ gboolean exists;
+
+ tmp = g_build_filename (g_get_user_config_dir (),
+ "gnome-session",
+ "saved-session.new",
+ NULL);
+
+ exists = ensure_dir_exists (tmp);
+
+ if (G_UNLIKELY (!exists)) {
+ g_warning ("GsmSessionSave: could not create directory for saved session: %s", tmp);
+ g_free (tmp);
+ return NULL;
+ } else {
+ /* make sure it's empty */
+ GDir *dir;
+ const char *filename;
+
+ dir = g_dir_open (tmp, 0, NULL);
+ if (dir) {
+ while ((filename = g_dir_read_name (dir))) {
+ char *path = g_build_filename (tmp, filename,
+ NULL);
+ g_unlink (path);
+ }
+ g_dir_close (dir);
+ }
+ }
+
+ return tmp;
+}
+
const gchar *
gsm_util_get_saved_session_dir (void)
{
Modified: trunk/gnome-session/gsm-util.h
==============================================================================
--- trunk/gnome-session/gsm-util.h (original)
+++ trunk/gnome-session/gsm-util.h Tue Mar 24 22:51:44 2009
@@ -27,6 +27,8 @@
char * gsm_util_find_desktop_file_for_app_name (const char *app_name,
char **dirs);
+gchar *gsm_util_get_empty_tmp_session_dir (void);
+
const char *gsm_util_get_saved_session_dir (void);
gchar** gsm_util_get_app_dirs (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]