summaryrefslogtreecommitdiff
path: root/capplets/theme-switcher/theme-switcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'capplets/theme-switcher/theme-switcher.c')
-rw-r--r--capplets/theme-switcher/theme-switcher.c35
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);
}