diff options
Diffstat (limited to 'capplets/theme-switcher/theme-switcher.c')
-rw-r--r-- | capplets/theme-switcher/theme-switcher.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/capplets/theme-switcher/theme-switcher.c b/capplets/theme-switcher/theme-switcher.c index 937a8e0ef..244d244c3 100644 --- a/capplets/theme-switcher/theme-switcher.c +++ b/capplets/theme-switcher/theme-switcher.c @@ -451,7 +451,7 @@ transfer_cancel_cb (GtkWidget *dlg, gchar *path) * see bugzilla.gnome.org #86141 for details */ static gboolean -transfer_done_idle_cb (gpointer data) +transfer_done_targz_idle_cb (gpointer data) { int status; gchar *command; @@ -496,12 +496,43 @@ window_show_manage_themes (GtkWidget *button, gpointer data) g_free (command); } + +/* this works around problems when doing fork/exec in a threaded app + * with some locks being held/waited on in different threads. + * + * we do the idle callback so that the async xfer has finished and + * cleaned up its vfs job. otherwise it seems the slave thread gets + * woken up and it removes itself from the job queue before it is + * supposed to. very strange. + * + * see bugzilla.gnome.org #86141 for details + */ +static gboolean +transfer_done_tarbz2_idle_cb (gpointer data) +{ + int status; + gchar *command; + gchar *path = data; + + /* this should be something more clever and nonblocking */ + command = g_strdup_printf ("sh -c 'bzip2 -d -c < \"%s\" | tar xf - -C \"%s/.themes\"'", + path, g_get_home_dir ()); + if (g_spawn_command_line_sync (command, NULL, NULL, &status, NULL) && status == 0) + gnome_vfs_unlink (path); + g_free (command); + g_free (path); + + return FALSE; +} + static void transfer_done_cb (GtkWidget *dlg, gchar *path) { int len = strlen (path); if (path && len > 7 && !strcmp (path + len - 7, ".tar.gz")) - g_idle_add (transfer_done_idle_cb, path); + g_idle_add (transfer_done_targz_idle_cb, path); + if (path && len > 8 && !strcmp (path + len - 8, ".tar.bz2")) + g_idle_add (transfer_done_tarbz2_idle_cb, path); gtk_widget_destroy (dlg); } |