~ps-jenkins/unity-settings-daemon/ubuntu-vivid-proposed

« back to all changes in this revision

Viewing changes to debian/patches/git_revert_remove_automount_helper.patch

  • Committer: Robert Ancell
  • Date: 2013-11-13 01:33:12 UTC
  • Revision ID: robert.ancell@canonical.com-20131113013312-lqg7dhy39tvmjrda
Import packaging

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 465216015af24685e3f16e9c3618031970589785 Mon Sep 17 00:00:00 2001
 
2
From: Tim Lunn <tim@feathertop.org>
 
3
Date: Sun, 9 Jun 2013 10:04:48 +1000
 
4
Subject: [PATCH] Revert "automount: Remove fallback automount code"
 
5
 
 
6
This reverts commit 77a29fde9204a80ad3960fc6d50a733261fbfbfe.
 
7
 
 
8
+ ported to use dbus session tracking
 
9
+ autostart on unity session
 
10
 
 
11
---
 
12
 configure.ac                                       |   7 +
 
13
 plugins/Makefile.am                                |   1 +
 
14
 plugins/automount/Makefile.am                      |  36 +
 
15
 plugins/automount/gnome-fallback-mount-helper.c    |  64 ++
 
16
 .../gnome-fallback-mount-helper.desktop.in.in      |  12 +
 
17
 plugins/automount/gsd-automount-manager.c          | 573 ++++++++++++
 
18
 plugins/automount/gsd-automount-manager.h          |  58 ++
 
19
 plugins/automount/gsd-autorun.c                    | 975 +++++++++++++++++++++
 
20
 plugins/automount/gsd-autorun.h                    |  53 ++
 
21
 po/POTFILES.in                                     |   3 +
 
22
 10 files changed, 1782 insertions(+)
 
23
 create mode 100644 plugins/automount/Makefile.am
 
24
 create mode 100644 plugins/automount/gnome-fallback-mount-helper.c
 
25
 create mode 100644 plugins/automount/gnome-fallback-mount-helper.desktop.in.in
 
26
 create mode 100644 plugins/automount/gsd-automount-manager.c
 
27
 create mode 100644 plugins/automount/gsd-automount-manager.h
 
28
 create mode 100644 plugins/automount/gsd-autorun.c
 
29
 create mode 100644 plugins/automount/gsd-autorun.h
 
30
 
 
31
Index: gnome-settings-daemon-3.8.5/configure.ac
 
32
===================================================================
 
33
--- gnome-settings-daemon-3.8.5.orig/configure.ac       2013-11-12 16:32:41.742469452 +1300
 
34
+++ gnome-settings-daemon-3.8.5/configure.ac    2013-11-12 16:32:41.734469452 +1300
 
35
@@ -146,6 +146,12 @@
 
36
 PKG_CHECK_MODULES(COMMON, x11 kbproto xi)
 
37
 
 
38
 dnl ---------------------------------------------------------------------------
 
39
+dnl - automount
 
40
+dnl ---------------------------------------------------------------------------
 
41
+
 
42
+PKG_CHECK_MODULES(AUTOMOUNT, x11 kbproto)
 
43
+
 
44
+dnl ---------------------------------------------------------------------------
 
45
 dnl - XTest
 
46
 dnl ---------------------------------------------------------------------------
 
47
 
 
48
@@ -495,6 +501,7 @@
 
49
 plugins/Makefile
 
50
 plugins/a11y-keyboard/Makefile
 
51
 plugins/a11y-settings/Makefile
 
52
+plugins/automount/Makefile
 
53
 plugins/background/Makefile
 
54
 plugins/clipboard/Makefile
 
55
 plugins/color/Makefile
 
56
Index: gnome-settings-daemon-3.8.5/plugins/Makefile.am
 
57
===================================================================
 
58
--- gnome-settings-daemon-3.8.5.orig/plugins/Makefile.am        2013-11-12 16:32:41.742469452 +1300
 
59
+++ gnome-settings-daemon-3.8.5/plugins/Makefile.am     2013-11-12 16:32:41.734469452 +1300
 
60
@@ -3,6 +3,7 @@
 
61
 enabled_plugins =      \
 
62
        a11y-keyboard   \
 
63
        a11y-settings   \
 
64
+    automount       \
 
65
        background      \
 
66
        clipboard       \
 
67
        color           \
 
68
Index: gnome-settings-daemon-3.8.5/plugins/automount/Makefile.am
 
69
===================================================================
 
70
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
71
+++ gnome-settings-daemon-3.8.5/plugins/automount/Makefile.am   2013-11-12 16:32:41.734469452 +1300
 
72
@@ -0,0 +1,36 @@
 
73
+libexec_PROGRAMS = gnome-fallback-mount-helper
 
74
+
 
75
+gnome_fallback_mount_helper_SOURCES = \
 
76
+       gnome-fallback-mount-helper.c \
 
77
+       gsd-automount-manager.c \
 
78
+       gsd-automount-manager.h \
 
79
+       gsd-autorun.c \
 
80
+       gsd-autorun.h
 
81
+
 
82
+gnome_fallback_mount_helper_CPPFLAGS = \
 
83
+       -I$(top_srcdir)/gnome-settings-daemon           \
 
84
+       -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
 
85
+       $(AM_CPPFLAGS)
 
86
+
 
87
+gnome_fallback_mount_helper_CFLAGS =   \
 
88
+       $(SETTINGS_PLUGIN_CFLAGS)       \
 
89
+       $(AUTOMOUNT_CFLAGS)
 
90
+
 
91
+gnome_fallback_mount_helper_LDADD =    \
 
92
+       $(SETTINGS_PLUGIN_LIBS)         \
 
93
+       $(AUTOMOUNT_LIBS)               \
 
94
+       $(top_builddir)/gnome-settings-daemon/libgsd.la
 
95
+
 
96
+autostartdir = $(sysconfdir)/xdg/autostart
 
97
+autostart_in_files = gnome-fallback-mount-helper.desktop.in
 
98
+autostart_in_in_files = gnome-fallback-mount-helper.desktop.in.in
 
99
+autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
 
100
+
 
101
+$(autostart_in_files): $(autostart_in_in_files)
 
102
+       @sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@
 
103
+
 
104
+@INTLTOOL_DESKTOP_RULE@
 
105
+
 
106
+EXTRA_DIST = $(autostart_in_in_files)
 
107
+
 
108
+CLEANFILES = $(autostart_DATA) $(autostart_in_files)
 
109
Index: gnome-settings-daemon-3.8.5/plugins/automount/gnome-fallback-mount-helper.c
 
110
===================================================================
 
111
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
112
+++ gnome-settings-daemon-3.8.5/plugins/automount/gnome-fallback-mount-helper.c 2013-11-12 16:32:41.734469452 +1300
 
113
@@ -0,0 +1,64 @@
 
114
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
115
+ *
 
116
+ * Copyright (C) 2010 Red Hat, Inc.
 
117
+ *
 
118
+ * This program is free software; you can redistribute it and/or modify
 
119
+ * it under the terms of the GNU General Public License as published by
 
120
+ * the Free Software Foundation; either version 2 of the License, or
 
121
+ * (at your option) any later version.
 
122
+ *
 
123
+ * This program is distributed in the hope that it will be useful,
 
124
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
125
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
126
+ * GNU General Public License for more details.
 
127
+ *
 
128
+ * You should have received a copy of the GNU General Public License
 
129
+ * along with this program; if not, write to the Free Software
 
130
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
131
+ *
 
132
+ * Author: Tomas Bzatek <tbzatek@redhat.com>
 
133
+ */
 
134
+
 
135
+#include "config.h"
 
136
+
 
137
+#include <glib.h>
 
138
+#include <glib/gi18n.h>
 
139
+#include <unistd.h>
 
140
+#include <gtk/gtk.h>
 
141
+
 
142
+#include "gsd-automount-manager.h"
 
143
+
 
144
+int
 
145
+main (int argc,
 
146
+      char **argv)
 
147
+{
 
148
+        GMainLoop *loop;
 
149
+        GsdAutomountManager *manager;
 
150
+        GError *error = NULL;
 
151
+
 
152
+        gtk_init (&argc, &argv);
 
153
+
 
154
+        bindtextdomain (GETTEXT_PACKAGE, GNOME_SETTINGS_LOCALEDIR);
 
155
+        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
156
+        textdomain (GETTEXT_PACKAGE);
 
157
+
 
158
+        loop = g_main_loop_new (NULL, FALSE);
 
159
+        manager = gsd_automount_manager_new ();
 
160
+
 
161
+        gsd_automount_manager_start (manager, &error);
 
162
+
 
163
+        if (error != NULL) {
 
164
+                g_printerr ("Unable to start the mount manager: %s",
 
165
+                            error->message);
 
166
+
 
167
+                g_error_free (error);
 
168
+                _exit (1);
 
169
+        }
 
170
+
 
171
+        g_main_loop_run (loop);
 
172
+
 
173
+        gsd_automount_manager_stop (manager);
 
174
+        g_main_loop_unref (loop);
 
175
+
 
176
+        return 0;
 
177
+}
 
178
Index: gnome-settings-daemon-3.8.5/plugins/automount/gnome-fallback-mount-helper.desktop.in.in
 
179
===================================================================
 
180
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
181
+++ gnome-settings-daemon-3.8.5/plugins/automount/gnome-fallback-mount-helper.desktop.in.in     2013-11-12 16:32:41.734469452 +1300
 
182
@@ -0,0 +1,12 @@
 
183
+[Desktop Entry]
 
184
+_Name=Mount Helper
 
185
+_Comment=Automount and autorun plugged devices
 
186
+Exec=@LIBEXECDIR@/gnome-fallback-mount-helper
 
187
+Icon=drive-optical
 
188
+Terminal=false
 
189
+Type=Application
 
190
+Categories=
 
191
+NoDisplay=true
 
192
+OnlyShowIn=GNOME;Unity;
 
193
+X-GNOME-Autostart-Notify=true
 
194
+AutostartCondition=GNOME3 unless-session gnome
 
195
Index: gnome-settings-daemon-3.8.5/plugins/automount/gsd-automount-manager.c
 
196
===================================================================
 
197
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
198
+++ gnome-settings-daemon-3.8.5/plugins/automount/gsd-automount-manager.c       2013-11-12 16:32:41.734469452 +1300
 
199
@@ -0,0 +1,573 @@
 
200
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
201
+ *
 
202
+ * Copyright (C) 2010 Red Hat, Inc.
 
203
+ *
 
204
+ * This program is free software; you can redistribute it and/or modify
 
205
+ * it under the terms of the GNU General Public License as published by
 
206
+ * the Free Software Foundation; either version 2 of the License, or
 
207
+ * (at your option) any later version.
 
208
+ *
 
209
+ * This program is distributed in the hope that it will be useful,
 
210
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
211
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
212
+ * GNU General Public License for more details.
 
213
+ *
 
214
+ * You should have received a copy of the GNU General Public License
 
215
+ * along with this program; if not, write to the Free Software
 
216
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
217
+ *
 
218
+ * Author: Tomas Bzatek <tbzatek@redhat.com>
 
219
+ */
 
220
+
 
221
+#include "config.h"
 
222
+
 
223
+#include <stdlib.h>
 
224
+#include <string.h>
 
225
+
 
226
+#include <glib.h>
 
227
+#include <glib/gi18n.h>
 
228
+#include <gio/gio.h>
 
229
+
 
230
+#include "gnome-settings-profile.h"
 
231
+#include "gnome-settings-session.h"
 
232
+#include "gsd-automount-manager.h"
 
233
+#include "gsd-autorun.h"
 
234
+
 
235
+#define GSD_AUTOMOUNT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_AUTOMOUNT_MANAGER, GsdAutomountManagerPrivate))
 
236
+
 
237
+struct GsdAutomountManagerPrivate
 
238
+{
 
239
+        GSettings   *settings;
 
240
+
 
241
+       GVolumeMonitor *volume_monitor;
 
242
+       unsigned int automount_idle_id;
 
243
+
 
244
+        GDBusProxy *session;
 
245
+        gboolean session_is_active;
 
246
+        gboolean screensaver_active;
 
247
+        guint ss_watch_id;
 
248
+        GDBusProxy *ss_proxy;
 
249
+
 
250
+        GList *volume_queue;
 
251
+};
 
252
+
 
253
+static void     gsd_automount_manager_class_init  (GsdAutomountManagerClass *klass);
 
254
+static void     gsd_automount_manager_init        (GsdAutomountManager      *gsd_automount_manager);
 
255
+
 
256
+G_DEFINE_TYPE (GsdAutomountManager, gsd_automount_manager, G_TYPE_OBJECT)
 
257
+
 
258
+static GtkDialog *
 
259
+show_error_dialog (const char *primary_text,
 
260
+                  const char *secondary_text)
 
261
+{
 
262
+       GtkWidget *dialog;
 
263
+
 
264
+       dialog = gtk_message_dialog_new (NULL,
 
265
+                                        0,
 
266
+                                        GTK_MESSAGE_ERROR,
 
267
+                                        GTK_BUTTONS_OK,
 
268
+                                        "%s", "");
 
269
+
 
270
+       g_object_set (dialog,
 
271
+                     "text", primary_text,
 
272
+                     "secondary-text", secondary_text,
 
273
+                     NULL);
 
274
+
 
275
+       gtk_widget_show (GTK_WIDGET (dialog));
 
276
+
 
277
+       g_signal_connect (dialog, "response",
 
278
+                         G_CALLBACK (gtk_widget_destroy), NULL);
 
279
+
 
280
+       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
281
+
 
282
+       return GTK_DIALOG (dialog);
 
283
+}
 
284
+
 
285
+static void
 
286
+startup_volume_mount_cb (GObject *source_object,
 
287
+                        GAsyncResult *res,
 
288
+                        gpointer user_data)
 
289
+{
 
290
+       g_volume_mount_finish (G_VOLUME (source_object), res, NULL);
 
291
+}
 
292
+
 
293
+static void
 
294
+automount_all_volumes (GsdAutomountManager *manager)
 
295
+{
 
296
+       GList *volumes, *l;
 
297
+       GMount *mount;
 
298
+       GVolume *volume;
 
299
+
 
300
+       if (g_settings_get_boolean (manager->priv->settings, "automount")) {
 
301
+               /* automount all mountable volumes at start-up */
 
302
+               volumes = g_volume_monitor_get_volumes (manager->priv->volume_monitor);
 
303
+               for (l = volumes; l != NULL; l = l->next) {
 
304
+                       volume = l->data;
 
305
+
 
306
+                       if (!g_volume_should_automount (volume) ||
 
307
+                           !g_volume_can_mount (volume)) {
 
308
+                               continue;
 
309
+                       }
 
310
+
 
311
+                       mount = g_volume_get_mount (volume);
 
312
+                       if (mount != NULL) {
 
313
+                               g_object_unref (mount);
 
314
+                               continue;
 
315
+                       }
 
316
+
 
317
+                       /* pass NULL as GMountOperation to avoid user interaction */
 
318
+                       g_volume_mount (volume, 0, NULL, NULL, startup_volume_mount_cb, NULL);
 
319
+               }
 
320
+               g_list_free_full (volumes, g_object_unref);
 
321
+       }
 
322
+}
 
323
+
 
324
+static gboolean
 
325
+automount_all_volumes_idle_cb (gpointer data)
 
326
+{
 
327
+       GsdAutomountManager *manager = GSD_AUTOMOUNT_MANAGER (data);
 
328
+
 
329
+       automount_all_volumes (manager);
 
330
+
 
331
+       manager->priv->automount_idle_id = 0;
 
332
+       return FALSE;
 
333
+}
 
334
+
 
335
+static void
 
336
+volume_mount_cb (GObject *source_object,
 
337
+                GAsyncResult *res,
 
338
+                gpointer user_data)
 
339
+{
 
340
+       GMountOperation *mount_op = user_data;
 
341
+       GError *error;
 
342
+       char *primary;
 
343
+       char *name;
 
344
+
 
345
+       error = NULL;
 
346
+       gsd_allow_autorun_for_volume_finish (G_VOLUME (source_object));
 
347
+       if (!g_volume_mount_finish (G_VOLUME (source_object), res, &error)) {
 
348
+               if (error->code != G_IO_ERROR_FAILED_HANDLED) {
 
349
+                       name = g_volume_get_name (G_VOLUME (source_object));
 
350
+                       primary = g_strdup_printf (_("Unable to mount %s"), name);
 
351
+                       g_free (name);
 
352
+                       show_error_dialog (primary,
 
353
+                                          error->message);
 
354
+                       g_free (primary);
 
355
+               }
 
356
+               g_error_free (error);
 
357
+       }
 
358
+
 
359
+       g_object_unref (mount_op);
 
360
+}
 
361
+
 
362
+static void
 
363
+do_mount_volume (GVolume *volume)
 
364
+{
 
365
+       GMountOperation *mount_op;
 
366
+
 
367
+       mount_op = gtk_mount_operation_new (NULL);
 
368
+       g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
 
369
+
 
370
+       gsd_allow_autorun_for_volume (volume);
 
371
+       g_volume_mount (volume, 0, mount_op, NULL, volume_mount_cb, mount_op);
 
372
+}
 
373
+
 
374
+static void
 
375
+check_volume_queue (GsdAutomountManager *manager)
 
376
+{
 
377
+        GList *l;
 
378
+        GVolume *volume;
 
379
+
 
380
+        if (manager->priv->screensaver_active)
 
381
+                return;
 
382
+
 
383
+        l = manager->priv->volume_queue;
 
384
+
 
385
+        while (l != NULL) {
 
386
+                volume = l->data;
 
387
+
 
388
+                do_mount_volume (volume);
 
389
+                manager->priv->volume_queue =
 
390
+                        g_list_remove (manager->priv->volume_queue, volume);
 
391
+
 
392
+                g_object_unref (volume);
 
393
+                l = l->next;
 
394
+        }
 
395
+
 
396
+        manager->priv->volume_queue = NULL;
 
397
+}
 
398
+
 
399
+static void
 
400
+check_screen_lock_and_mount (GsdAutomountManager *manager,
 
401
+                             GVolume *volume)
 
402
+{
 
403
+        if (!manager->priv->session_is_active)
 
404
+                return;
 
405
+
 
406
+        if (manager->priv->screensaver_active) {
 
407
+                /* queue the volume, to mount it after the screensaver state changed */
 
408
+                g_debug ("Queuing volume %p", volume);
 
409
+                manager->priv->volume_queue = g_list_prepend (manager->priv->volume_queue,
 
410
+                                                              g_object_ref (volume));
 
411
+        } else {
 
412
+                /* mount it immediately */
 
413
+                do_mount_volume (volume);
 
414
+        }
 
415
+}
 
416
+
 
417
+static void
 
418
+volume_removed_callback (GVolumeMonitor *monitor,
 
419
+                         GVolume *volume,
 
420
+                         GsdAutomountManager *manager)
 
421
+{
 
422
+        g_debug ("Volume %p removed, removing from the queue", volume);
 
423
+
 
424
+        /* clear it from the queue, if present */
 
425
+        manager->priv->volume_queue =
 
426
+                g_list_remove (manager->priv->volume_queue, volume);
 
427
+}
 
428
+
 
429
+static void
 
430
+volume_added_callback (GVolumeMonitor *monitor,
 
431
+                      GVolume *volume,
 
432
+                      GsdAutomountManager *manager)
 
433
+{
 
434
+       if (g_settings_get_boolean (manager->priv->settings, "automount") &&
 
435
+           g_volume_should_automount (volume) &&
 
436
+           g_volume_can_mount (volume)) {
 
437
+                check_screen_lock_and_mount (manager, volume);
 
438
+       } else {
 
439
+               /* Allow gsd_autorun() to run. When the mount is later
 
440
+                * added programmatically (i.e. for a blank CD),
 
441
+                * gsd_autorun() will be called by mount_added_callback(). */
 
442
+               gsd_allow_autorun_for_volume (volume);
 
443
+               gsd_allow_autorun_for_volume_finish (volume);
 
444
+       }
 
445
+}
 
446
+
 
447
+static void
 
448
+autorun_show_window (GMount *mount, gpointer user_data)
 
449
+{
 
450
+       GFile *location;
 
451
+        char *uri;
 
452
+        GError *error;
 
453
+       char *primary;
 
454
+       char *name;
 
455
+
 
456
+       location = g_mount_get_root (mount);
 
457
+        uri = g_file_get_uri (location);
 
458
+
 
459
+        error = NULL;
 
460
+       /* use default folder handler */
 
461
+        if (! gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, &error)) {
 
462
+               name = g_mount_get_name (mount);
 
463
+               primary = g_strdup_printf (_("Unable to open a folder for %s"), name);
 
464
+               g_free (name);
 
465
+               show_error_dialog (primary,
 
466
+                                  error->message);
 
467
+               g_free (primary);
 
468
+               g_error_free (error);
 
469
+        }
 
470
+
 
471
+        g_free (uri);
 
472
+       g_object_unref (location);
 
473
+}
 
474
+
 
475
+static void
 
476
+mount_added_callback (GVolumeMonitor *monitor,
 
477
+                     GMount *mount,
 
478
+                     GsdAutomountManager *manager)
 
479
+{
 
480
+        /* don't autorun if the session is not active */
 
481
+        if (!manager->priv->session_is_active) {
 
482
+                return;
 
483
+        }
 
484
+
 
485
+       gsd_autorun (mount, manager->priv->settings, autorun_show_window, manager);
 
486
+}
 
487
+
 
488
+
 
489
+static void
 
490
+session_state_changed (GDBusProxy      *session,
 
491
+                       GVariant        *changed,
 
492
+                       char           **invalidated,
 
493
+                       GsdAutomountManager *manager)
 
494
+{
 
495
+        GsdAutomountManagerPrivate *p = manager->priv;
 
496
+
 
497
+        GVariant *v;
 
498
+
 
499
+        v = g_variant_lookup_value (changed, "SessionIsActive", G_VARIANT_TYPE_BOOLEAN);
 
500
+
 
501
+        if (v) {
 
502
+                gboolean active;
 
503
+
 
504
+                active = g_variant_get_boolean (v);
 
505
+                g_debug ("Received session is active change: now %s", active ? "active" : "inactive");
 
506
+                /* when doing the fast-user-switch into a new account,
 
507
+                 * ensure the new account is undimmed and with the backlight on */
 
508
+                if (active)
 
509
+                        p->session_is_active = TRUE;
 
510
+                else
 
511
+                        p->session_is_active = FALSE;
 
512
+
 
513
+                g_variant_unref (v);
 
514
+
 
515
+        }
 
516
+
 
517
+        if (!p->session_is_active) {
 
518
+                if (p->volume_queue != NULL) {
 
519
+                        g_list_free_full (p->volume_queue, g_object_unref);
 
520
+                        p->volume_queue = NULL;
 
521
+                }
 
522
+        }
 
523
+}
 
524
+
 
525
+static gboolean
 
526
+is_session_active (GsdAutomountManager *manager)
 
527
+{
 
528
+        GVariant *variant;
 
529
+        gboolean is_session_active = FALSE;
 
530
+
 
531
+        variant = g_dbus_proxy_get_cached_property (manager->priv->session,
 
532
+                                                    "SessionIsActive");
 
533
+        if (variant) {
 
534
+                is_session_active = g_variant_get_boolean (variant);
 
535
+                g_variant_unref (variant);
 
536
+        }
 
537
+
 
538
+        return is_session_active;
 
539
+}
 
540
+
 
541
+
 
542
+static void
 
543
+do_initialize_session (GsdAutomountManager *manager)
 
544
+{
 
545
+        manager->priv->session = gnome_settings_session_get_session_proxy ();
 
546
+        g_signal_connect (manager->priv->session, "g-properties-changed",
 
547
+                          G_CALLBACK (session_state_changed),
 
548
+                          manager);
 
549
+        manager->priv->session_is_active = is_session_active (manager);
 
550
+}
 
551
+
 
552
+#define SCREENSAVER_NAME "org.gnome.ScreenSaver"
 
553
+#define SCREENSAVER_PATH "/org/gnome/ScreenSaver"
 
554
+#define SCREENSAVER_INTERFACE "org.gnome.ScreenSaver"
 
555
+
 
556
+static void
 
557
+screensaver_signal_callback (GDBusProxy *proxy,
 
558
+                             const gchar *sender_name,
 
559
+                             const gchar *signal_name,
 
560
+                             GVariant *parameters,
 
561
+                             gpointer user_data)
 
562
+{
 
563
+        GsdAutomountManager *manager = user_data;
 
564
+
 
565
+        if (g_strcmp0 (signal_name, "ActiveChanged") == 0) {
 
566
+                g_variant_get (parameters, "(b)", &manager->priv->screensaver_active);
 
567
+                g_debug ("Screensaver active changed to %d", manager->priv->screensaver_active);
 
568
+
 
569
+                check_volume_queue (manager);
 
570
+        }
 
571
+}
 
572
+
 
573
+static void
 
574
+screensaver_get_active_ready_cb (GObject *source,
 
575
+                                 GAsyncResult *res,
 
576
+                                 gpointer user_data)
 
577
+{
 
578
+        GsdAutomountManager *manager = user_data;
 
579
+        GDBusProxy *proxy = manager->priv->ss_proxy;
 
580
+        GVariant *result;
 
581
+        GError *error = NULL;
 
582
+
 
583
+        result = g_dbus_proxy_call_finish (proxy,
 
584
+                                           res,
 
585
+                                           &error);
 
586
+
 
587
+        if (error != NULL) {
 
588
+                g_warning ("Can't call GetActive() on the ScreenSaver object: %s",
 
589
+                           error->message);
 
590
+                g_error_free (error);
 
591
+
 
592
+                return;
 
593
+        }
 
594
+
 
595
+        g_variant_get (result, "(b)", &manager->priv->screensaver_active);
 
596
+        g_variant_unref (result);
 
597
+
 
598
+        g_debug ("Screensaver GetActive() returned %d", manager->priv->screensaver_active);
 
599
+}
 
600
+
 
601
+static void
 
602
+screensaver_proxy_ready_cb (GObject *source,
 
603
+                            GAsyncResult *res,
 
604
+                            gpointer user_data)
 
605
+{
 
606
+        GsdAutomountManager *manager = user_data;
 
607
+        GError *error = NULL;
 
608
+        GDBusProxy *ss_proxy;
 
609
+
 
610
+        ss_proxy = g_dbus_proxy_new_finish (res, &error);
 
611
+
 
612
+        if (error != NULL) {
 
613
+                g_warning ("Can't get proxy for the ScreenSaver object: %s",
 
614
+                           error->message);
 
615
+                g_error_free (error);
 
616
+
 
617
+                return;
 
618
+        }
 
619
+
 
620
+        g_debug ("ScreenSaver proxy ready");
 
621
+
 
622
+        manager->priv->ss_proxy = ss_proxy;
 
623
+
 
624
+        g_signal_connect (ss_proxy, "g-signal",
 
625
+                          G_CALLBACK (screensaver_signal_callback), manager);
 
626
+
 
627
+        g_dbus_proxy_call (ss_proxy,
 
628
+                           "GetActive",
 
629
+                           NULL,
 
630
+                           G_DBUS_CALL_FLAGS_NO_AUTO_START,
 
631
+                           -1,
 
632
+                           NULL,
 
633
+                           screensaver_get_active_ready_cb,
 
634
+                           manager);
 
635
+}
 
636
+
 
637
+static void
 
638
+screensaver_appeared_callback (GDBusConnection *connection,
 
639
+                               const gchar *name,
 
640
+                               const gchar *name_owner,
 
641
+                               gpointer user_data)
 
642
+{
 
643
+        GsdAutomountManager *manager = user_data;
 
644
+
 
645
+        g_debug ("ScreenSaver name appeared");
 
646
+
 
647
+        manager->priv->screensaver_active = FALSE;
 
648
+
 
649
+        g_dbus_proxy_new (connection,
 
650
+                          G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
 
651
+                          NULL,
 
652
+                          name,
 
653
+                          SCREENSAVER_PATH,
 
654
+                          SCREENSAVER_INTERFACE,
 
655
+                          NULL,
 
656
+                          screensaver_proxy_ready_cb,
 
657
+                          manager);
 
658
+}
 
659
+
 
660
+static void
 
661
+screensaver_vanished_callback (GDBusConnection *connection,
 
662
+                               const gchar *name,
 
663
+                               gpointer user_data)
 
664
+{
 
665
+        GsdAutomountManager *manager = user_data;
 
666
+
 
667
+        g_debug ("ScreenSaver name vanished");
 
668
+
 
669
+        manager->priv->screensaver_active = FALSE;
 
670
+        g_clear_object (&manager->priv->ss_proxy);
 
671
+
 
672
+        /* in this case force a clear of the volume queue, without
 
673
+         * mounting them.
 
674
+         */
 
675
+        if (manager->priv->volume_queue != NULL) {
 
676
+                g_list_free_full (manager->priv->volume_queue, g_object_unref);
 
677
+                manager->priv->volume_queue = NULL;
 
678
+        }
 
679
+}
 
680
+
 
681
+static void
 
682
+do_initialize_screensaver (GsdAutomountManager *manager)
 
683
+{
 
684
+        GsdAutomountManagerPrivate *p = manager->priv;
 
685
+
 
686
+        p->ss_watch_id =
 
687
+                g_bus_watch_name (G_BUS_TYPE_SESSION,
 
688
+                                  SCREENSAVER_NAME,
 
689
+                                  G_BUS_NAME_WATCHER_FLAGS_NONE,
 
690
+                                  screensaver_appeared_callback,
 
691
+                                  screensaver_vanished_callback,
 
692
+                                  manager,
 
693
+                                  NULL);
 
694
+}
 
695
+
 
696
+static void
 
697
+setup_automounter (GsdAutomountManager *manager)
 
698
+{
 
699
+        do_initialize_session (manager);
 
700
+        do_initialize_screensaver (manager);
 
701
+
 
702
+       manager->priv->volume_monitor = g_volume_monitor_get ();
 
703
+       g_signal_connect_object (manager->priv->volume_monitor, "mount-added",
 
704
+                                G_CALLBACK (mount_added_callback), manager, 0);
 
705
+       g_signal_connect_object (manager->priv->volume_monitor, "volume-added",
 
706
+                                G_CALLBACK (volume_added_callback), manager, 0);
 
707
+       g_signal_connect_object (manager->priv->volume_monitor, "volume-removed",
 
708
+                                G_CALLBACK (volume_removed_callback), manager, 0);
 
709
+
 
710
+       manager->priv->automount_idle_id =
 
711
+               g_idle_add_full (G_PRIORITY_LOW,
 
712
+                                automount_all_volumes_idle_cb,
 
713
+                                manager, NULL);
 
714
+}
 
715
+
 
716
+gboolean
 
717
+gsd_automount_manager_start (GsdAutomountManager *manager,
 
718
+                                       GError              **error)
 
719
+{
 
720
+        g_debug ("Starting automounting manager");
 
721
+        gnome_settings_profile_start (NULL);
 
722
+
 
723
+        manager->priv->settings = g_settings_new ("org.gnome.desktop.media-handling");
 
724
+        setup_automounter (manager);
 
725
+
 
726
+        gnome_settings_profile_end (NULL);
 
727
+
 
728
+        return TRUE;
 
729
+}
 
730
+
 
731
+void
 
732
+gsd_automount_manager_stop (GsdAutomountManager *manager)
 
733
+{
 
734
+        GsdAutomountManagerPrivate *p = manager->priv;
 
735
+
 
736
+        g_debug ("Stopping automounting manager");
 
737
+
 
738
+        g_clear_object (&p->session);
 
739
+        g_clear_object (&p->volume_monitor);
 
740
+        g_clear_object (&p->settings);
 
741
+        g_clear_object (&p->ss_proxy);
 
742
+
 
743
+        g_bus_unwatch_name (p->ss_watch_id);
 
744
+
 
745
+        if (p->volume_queue != NULL) {
 
746
+                g_list_free_full (p->volume_queue, g_object_unref);
 
747
+                p->volume_queue = NULL;
 
748
+        }
 
749
+
 
750
+        if (p->automount_idle_id != 0) {
 
751
+                g_source_remove (p->automount_idle_id);
 
752
+                p->automount_idle_id = 0;
 
753
+        }
 
754
+}
 
755
+
 
756
+static void
 
757
+gsd_automount_manager_class_init (GsdAutomountManagerClass *klass)
 
758
+{
 
759
+        g_type_class_add_private (klass, sizeof (GsdAutomountManagerPrivate));
 
760
+}
 
761
+
 
762
+static void
 
763
+gsd_automount_manager_init (GsdAutomountManager *manager)
 
764
+{
 
765
+        manager->priv = GSD_AUTOMOUNT_MANAGER_GET_PRIVATE (manager);
 
766
+}
 
767
+
 
768
+GsdAutomountManager *
 
769
+gsd_automount_manager_new (void)
 
770
+{
 
771
+        return GSD_AUTOMOUNT_MANAGER (g_object_new (GSD_TYPE_AUTOMOUNT_MANAGER, NULL));
 
772
+}
 
773
Index: gnome-settings-daemon-3.8.5/plugins/automount/gsd-automount-manager.h
 
774
===================================================================
 
775
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
776
+++ gnome-settings-daemon-3.8.5/plugins/automount/gsd-automount-manager.h       2013-11-12 16:32:41.734469452 +1300
 
777
@@ -0,0 +1,58 @@
 
778
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
779
+ *
 
780
+ * Copyright (C) 2010 Red Hat, Inc.
 
781
+ *
 
782
+ * This program is free software; you can redistribute it and/or modify
 
783
+ * it under the terms of the GNU General Public License as published by
 
784
+ * the Free Software Foundation; either version 2 of the License, or
 
785
+ * (at your option) any later version.
 
786
+ *
 
787
+ * This program is distributed in the hope that it will be useful,
 
788
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
789
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
790
+ * GNU General Public License for more details.
 
791
+ *
 
792
+ * You should have received a copy of the GNU General Public License
 
793
+ * along with this program; if not, write to the Free Software
 
794
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
795
+ *
 
796
+ * Author: Tomas Bzatek <tbzatek@redhat.com>
 
797
+ */
 
798
+
 
799
+#ifndef __GSD_AUTOMOUNT_MANAGER_H
 
800
+#define __GSD_AUTOMOUNT_MANAGER_H
 
801
+
 
802
+#include <glib-object.h>
 
803
+
 
804
+G_BEGIN_DECLS
 
805
+
 
806
+#define GSD_TYPE_AUTOMOUNT_MANAGER         (gsd_automount_manager_get_type ())
 
807
+#define GSD_AUTOMOUNT_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_AUTOMOUNT_MANAGER, GsdAutomountManager))
 
808
+#define GSD_AUTOMOUNT_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_AUTOMOUNT_MANAGER, GsdAutomountManagerClass))
 
809
+#define GSD_IS_AUTOMOUNT_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_AUTOMOUNT_MANAGER))
 
810
+#define GSD_IS_AUTOMOUNT_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_AUTOMOUNT_MANAGER))
 
811
+#define GSD_AUTOMOUNT_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_AUTOMOUNT_MANAGER, GsdAutomountManagerClass))
 
812
+
 
813
+typedef struct GsdAutomountManagerPrivate GsdAutomountManagerPrivate;
 
814
+
 
815
+typedef struct
 
816
+{
 
817
+        GObject                     parent;
 
818
+        GsdAutomountManagerPrivate *priv;
 
819
+} GsdAutomountManager;
 
820
+
 
821
+typedef struct
 
822
+{
 
823
+        GObjectClass   parent_class;
 
824
+} GsdAutomountManagerClass;
 
825
+
 
826
+GType                   gsd_automount_manager_get_type            (void);
 
827
+
 
828
+GsdAutomountManager *   gsd_automount_manager_new                 (void);
 
829
+gboolean                gsd_automount_manager_start               (GsdAutomountManager *manager,
 
830
+                                                                   GError              **error);
 
831
+void                    gsd_automount_manager_stop                (GsdAutomountManager *manager);
 
832
+
 
833
+G_END_DECLS
 
834
+
 
835
+#endif /* __GSD_AUTOMOUNT_MANAGER_H */
 
836
Index: gnome-settings-daemon-3.8.5/plugins/automount/gsd-autorun.c
 
837
===================================================================
 
838
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
839
+++ gnome-settings-daemon-3.8.5/plugins/automount/gsd-autorun.c 2013-11-12 16:32:41.738469452 +1300
 
840
@@ -0,0 +1,975 @@
 
841
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
 
842
+
 
843
+/*
 
844
+ * gsd-automount.c: helpers for automounting hotplugged volumes
 
845
+ *
 
846
+ * Copyright (C) 2008, 2010 Red Hat, Inc.
 
847
+ *
 
848
+ * Nautilus is free software; you can redistribute it and/or modify
 
849
+ * it under the terms of the GNU General Public License as published by
 
850
+ * the Free Software Foundation; either version 2 of the License, or
 
851
+ * (at your option) any later version.
 
852
+ *
 
853
+ * This program is distributed in the hope that it will be useful,
 
854
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
855
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
856
+ * GNU General Public License for more details.
 
857
+ *
 
858
+ * You should have received a copy of the GNU General Public License
 
859
+ * along with this program; if not, write to the Free Software
 
860
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
861
+ *
 
862
+ * Authors: David Zeuthen <davidz@redhat.com>
 
863
+ *          Cosimo Cecchi <cosimoc@redhat.com>
 
864
+ */
 
865
+
 
866
+#include <config.h>
 
867
+#include <string.h>
 
868
+#include <glib/gi18n.h>
 
869
+#include <gio/gio.h>
 
870
+#include <gtk/gtk.h>
 
871
+#include <gdk/gdkx.h>
 
872
+#include <X11/XKBlib.h>
 
873
+#include <gdk/gdkkeysyms.h>
 
874
+
 
875
+#include "gsd-autorun.h"
 
876
+
 
877
+static gboolean should_autorun_mount (GMount *mount);
 
878
+
 
879
+#define CUSTOM_ITEM_ASK "gsd-item-ask"
 
880
+#define CUSTOM_ITEM_DO_NOTHING "gsd-item-do-nothing"
 
881
+#define CUSTOM_ITEM_OPEN_FOLDER "gsd-item-open-folder"
 
882
+
 
883
+typedef struct
 
884
+{
 
885
+       GtkWidget *dialog;
 
886
+
 
887
+       GMount *mount;
 
888
+       gboolean should_eject;
 
889
+
 
890
+       gboolean selected_ignore;
 
891
+       gboolean selected_open_folder;
 
892
+       GAppInfo *selected_app;
 
893
+
 
894
+       gboolean remember;
 
895
+
 
896
+       char *x_content_type;
 
897
+
 
898
+       GsdAutorunOpenWindow open_window_func;
 
899
+       gpointer user_data;
 
900
+} AutorunDialogData;
 
901
+
 
902
+static int
 
903
+gsd_autorun_g_strv_find (char **strv, const char *find_me)
 
904
+{
 
905
+       guint index;
 
906
+
 
907
+       g_return_val_if_fail (find_me != NULL, -1);
 
908
+
 
909
+       for (index = 0; strv[index] != NULL; ++index) {
 
910
+               if (strcmp (strv[index], find_me) == 0) {
 
911
+                       return index;
 
912
+               }
 
913
+       }
 
914
+
 
915
+       return -1;
 
916
+}
 
917
+
 
918
+
 
919
+#define ICON_SIZE_STANDARD 48
 
920
+
 
921
+static gint
 
922
+get_icon_size_for_stock_size (GtkIconSize size)
 
923
+{
 
924
+       gint w, h;
 
925
+
 
926
+       if (gtk_icon_size_lookup (size, &w, &h)) {
 
927
+               return MAX (w, h);
 
928
+       }
 
929
+       return ICON_SIZE_STANDARD;
 
930
+}
 
931
+
 
932
+static GdkPixbuf *
 
933
+render_icon (GIcon *icon, gint icon_size)
 
934
+{
 
935
+       GdkPixbuf *pixbuf;
 
936
+       GtkIconInfo *info;
 
937
+
 
938
+       pixbuf = NULL;
 
939
+
 
940
+       if (G_IS_THEMED_ICON (icon)) {
 
941
+               gchar const * const *names;
 
942
+
 
943
+               info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (),
 
944
+                                                      icon,
 
945
+                                                      icon_size,
 
946
+                                                      0);
 
947
+
 
948
+               if (info) {
 
949
+                       pixbuf = gtk_icon_info_load_icon (info, NULL);
 
950
+                       gtk_icon_info_free (info);
 
951
+               }
 
952
+
 
953
+               if (pixbuf == NULL) {
 
954
+                       names = g_themed_icon_get_names (G_THEMED_ICON (icon));
 
955
+                       pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 
956
+                                                          *names,
 
957
+                                                          icon_size,
 
958
+                                                          0, NULL);
 
959
+               }
 
960
+       }
 
961
+       else
 
962
+       if (G_IS_FILE_ICON (icon)) {
 
963
+               GFile *icon_file;
 
964
+               gchar *path;
 
965
+
 
966
+               icon_file = g_file_icon_get_file (G_FILE_ICON (icon));
 
967
+               path = g_file_get_path (icon_file);
 
968
+               pixbuf = gdk_pixbuf_new_from_file_at_size (path,
 
969
+                                                          icon_size, icon_size,
 
970
+                                                          NULL);
 
971
+               g_free (path);
 
972
+               g_object_unref (G_OBJECT (icon_file));
 
973
+       }
 
974
+
 
975
+       return pixbuf;
 
976
+}
 
977
+
 
978
+static void
 
979
+gsd_autorun_get_preferences (const char *x_content_type,
 
980
+                             gboolean *pref_start_app,
 
981
+                             gboolean *pref_ignore,
 
982
+                             gboolean *pref_open_folder)
 
983
+{
 
984
+        GSettings *settings;
 
985
+       char **x_content_start_app;
 
986
+       char **x_content_ignore;
 
987
+       char **x_content_open_folder;
 
988
+
 
989
+       g_return_if_fail (pref_start_app != NULL);
 
990
+       g_return_if_fail (pref_ignore != NULL);
 
991
+       g_return_if_fail (pref_open_folder != NULL);
 
992
+
 
993
+        settings = g_settings_new ("org.gnome.desktop.media-handling");
 
994
+
 
995
+       *pref_start_app = FALSE;
 
996
+       *pref_ignore = FALSE;
 
997
+       *pref_open_folder = FALSE;
 
998
+       x_content_start_app = g_settings_get_strv (settings, "autorun-x-content-start-app");
 
999
+       x_content_ignore = g_settings_get_strv (settings, "autorun-x-content-ignore");
 
1000
+       x_content_open_folder = g_settings_get_strv (settings, "autorun-x-content-open-folder");
 
1001
+       if (x_content_start_app != NULL) {
 
1002
+               *pref_start_app = gsd_autorun_g_strv_find (x_content_start_app, x_content_type) != -1;
 
1003
+       }
 
1004
+       if (x_content_ignore != NULL) {
 
1005
+               *pref_ignore = gsd_autorun_g_strv_find (x_content_ignore, x_content_type) != -1;
 
1006
+       }
 
1007
+       if (x_content_open_folder != NULL) {
 
1008
+               *pref_open_folder = gsd_autorun_g_strv_find (x_content_open_folder, x_content_type) != -1;
 
1009
+       }
 
1010
+       g_strfreev (x_content_ignore);
 
1011
+       g_strfreev (x_content_start_app);
 
1012
+       g_strfreev (x_content_open_folder);
 
1013
+        g_object_unref (settings);
 
1014
+}
 
1015
+
 
1016
+static char **
 
1017
+remove_elem_from_str_array (char **v,
 
1018
+                            const char *s)
 
1019
+{
 
1020
+        GPtrArray *array;
 
1021
+        guint idx;
 
1022
+
 
1023
+        array = g_ptr_array_new ();
 
1024
+
 
1025
+        for (idx = 0; v[idx] != NULL; idx++) {
 
1026
+                if (g_strcmp0 (v[idx], s) == 0) {
 
1027
+                        continue;
 
1028
+                }
 
1029
+
 
1030
+                g_ptr_array_add (array, v[idx]);
 
1031
+        }
 
1032
+
 
1033
+        g_ptr_array_add (array, NULL);
 
1034
+
 
1035
+        g_free (v);
 
1036
+
 
1037
+        return (char **) g_ptr_array_free (array, FALSE);
 
1038
+}
 
1039
+
 
1040
+static char **
 
1041
+add_elem_to_str_array (char **v,
 
1042
+                       const char *s)
 
1043
+{
 
1044
+        GPtrArray *array;
 
1045
+        guint idx;
 
1046
+
 
1047
+        array = g_ptr_array_new ();
 
1048
+
 
1049
+        for (idx = 0; v[idx] != NULL; idx++) {
 
1050
+                g_ptr_array_add (array, v[idx]);
 
1051
+        }
 
1052
+
 
1053
+        g_ptr_array_add (array, g_strdup (s));
 
1054
+        g_ptr_array_add (array, NULL);
 
1055
+
 
1056
+        g_free (v);
 
1057
+
 
1058
+        return (char **) g_ptr_array_free (array, FALSE);
 
1059
+}
 
1060
+
 
1061
+static void
 
1062
+gsd_autorun_set_preferences (const char *x_content_type,
 
1063
+                             gboolean pref_start_app,
 
1064
+                             gboolean pref_ignore,
 
1065
+                             gboolean pref_open_folder)
 
1066
+{
 
1067
+        GSettings *settings;
 
1068
+       char **x_content_start_app;
 
1069
+       char **x_content_ignore;
 
1070
+       char **x_content_open_folder;
 
1071
+
 
1072
+       g_assert (x_content_type != NULL);
 
1073
+
 
1074
+       settings = g_settings_new ("org.gnome.desktop.media-handling");
 
1075
+
 
1076
+       x_content_start_app = g_settings_get_strv (settings, "autorun-x-content-start-app");
 
1077
+       x_content_ignore = g_settings_get_strv (settings, "autorun-x-content-ignore");
 
1078
+       x_content_open_folder = g_settings_get_strv (settings, "autorun-x-content-open-folder");
 
1079
+
 
1080
+       x_content_start_app = remove_elem_from_str_array (x_content_start_app, x_content_type);
 
1081
+       if (pref_start_app) {
 
1082
+               x_content_start_app = add_elem_to_str_array (x_content_start_app, x_content_type);
 
1083
+       }
 
1084
+       g_settings_set_strv (settings, "autorun-x-content-start-app", (const gchar * const*) x_content_start_app);
 
1085
+
 
1086
+       x_content_ignore = remove_elem_from_str_array (x_content_ignore, x_content_type);
 
1087
+       if (pref_ignore) {
 
1088
+               x_content_ignore = add_elem_to_str_array (x_content_ignore, x_content_type);
 
1089
+       }
 
1090
+       g_settings_set_strv (settings, "autorun-x-content-ignore", (const gchar * const*) x_content_ignore);
 
1091
+
 
1092
+       x_content_open_folder = remove_elem_from_str_array (x_content_open_folder, x_content_type);
 
1093
+       if (pref_open_folder) {
 
1094
+               x_content_open_folder = add_elem_to_str_array (x_content_open_folder, x_content_type);
 
1095
+       }
 
1096
+       g_settings_set_strv (settings, "autorun-x-content-open-folder", (const gchar * const*) x_content_open_folder);
 
1097
+
 
1098
+       g_strfreev (x_content_open_folder);
 
1099
+       g_strfreev (x_content_ignore);
 
1100
+       g_strfreev (x_content_start_app);
 
1101
+        g_object_unref (settings);
 
1102
+}
 
1103
+
 
1104
+static void
 
1105
+custom_item_activated_cb (GtkAppChooserButton *button,
 
1106
+                          const gchar *item,
 
1107
+                          gpointer user_data)
 
1108
+{
 
1109
+        gchar *content_type;
 
1110
+        AutorunDialogData *data = user_data;
 
1111
+
 
1112
+        content_type = gtk_app_chooser_get_content_type (GTK_APP_CHOOSER (button));
 
1113
+
 
1114
+        if (g_strcmp0 (item, CUSTOM_ITEM_ASK) == 0) {
 
1115
+                gsd_autorun_set_preferences (content_type,
 
1116
+                                             FALSE, FALSE, FALSE);
 
1117
+                data->selected_open_folder = FALSE;
 
1118
+                data->selected_ignore = FALSE;
 
1119
+        } else if (g_strcmp0 (item, CUSTOM_ITEM_OPEN_FOLDER) == 0) {
 
1120
+                gsd_autorun_set_preferences (content_type,
 
1121
+                                             FALSE, FALSE, TRUE);
 
1122
+                data->selected_open_folder = TRUE;
 
1123
+                data->selected_ignore = FALSE;
 
1124
+        } else if (g_strcmp0 (item, CUSTOM_ITEM_DO_NOTHING) == 0) {
 
1125
+                gsd_autorun_set_preferences (content_type,
 
1126
+                                             FALSE, TRUE, FALSE);
 
1127
+                data->selected_open_folder = FALSE;
 
1128
+                data->selected_ignore = TRUE;
 
1129
+        }
 
1130
+
 
1131
+        g_free (content_type);
 
1132
+}
 
1133
+
 
1134
+static void
 
1135
+combo_box_changed_cb (GtkComboBox *combo_box,
 
1136
+                      gpointer user_data)
 
1137
+{
 
1138
+        GAppInfo *info;
 
1139
+        AutorunDialogData *data = user_data;
 
1140
+
 
1141
+        info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (combo_box));
 
1142
+
 
1143
+        if (info == NULL)
 
1144
+                return;
 
1145
+
 
1146
+        g_clear_object (&data->selected_app);
 
1147
+        data->selected_app = info;
 
1148
+}
 
1149
+
 
1150
+static void
 
1151
+prepare_combo_box (GtkWidget *combo_box,
 
1152
+                  AutorunDialogData *data)
 
1153
+{
 
1154
+        GtkAppChooserButton *app_chooser = GTK_APP_CHOOSER_BUTTON (combo_box);
 
1155
+        GIcon *icon;
 
1156
+        gboolean pref_ask;
 
1157
+        gboolean pref_start_app;
 
1158
+        gboolean pref_ignore;
 
1159
+        gboolean pref_open_folder;
 
1160
+        GAppInfo *info;
 
1161
+        gchar *content_type;
 
1162
+
 
1163
+        content_type = gtk_app_chooser_get_content_type (GTK_APP_CHOOSER (app_chooser));
 
1164
+
 
1165
+        /* fetch preferences for this content type */
 
1166
+        gsd_autorun_get_preferences (content_type,
 
1167
+                                     &pref_start_app, &pref_ignore, &pref_open_folder);
 
1168
+        pref_ask = !pref_start_app && !pref_ignore && !pref_open_folder;
 
1169
+
 
1170
+        info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (combo_box));
 
1171
+
 
1172
+        /* append the separator only if we have >= 1 apps in the chooser */
 
1173
+        if (info != NULL) {
 
1174
+                gtk_app_chooser_button_append_separator (app_chooser);
 
1175
+                g_object_unref (info);
 
1176
+        }
 
1177
+
 
1178
+        icon = g_themed_icon_new (GTK_STOCK_DIALOG_QUESTION);
 
1179
+        gtk_app_chooser_button_append_custom_item (app_chooser, CUSTOM_ITEM_ASK,
 
1180
+                                                   _("Ask what to do"),
 
1181
+                                                   icon);
 
1182
+        g_object_unref (icon);
 
1183
+
 
1184
+        icon = g_themed_icon_new (GTK_STOCK_CLOSE);
 
1185
+        gtk_app_chooser_button_append_custom_item (app_chooser, CUSTOM_ITEM_DO_NOTHING,
 
1186
+                                                   _("Do Nothing"),
 
1187
+                                                   icon);
 
1188
+        g_object_unref (icon);
 
1189
+
 
1190
+        icon = g_themed_icon_new ("folder-open");
 
1191
+        gtk_app_chooser_button_append_custom_item (app_chooser, CUSTOM_ITEM_OPEN_FOLDER,
 
1192
+                                                   _("Open Folder"),
 
1193
+                                                   icon);
 
1194
+        g_object_unref (icon);
 
1195
+
 
1196
+        gtk_app_chooser_button_set_show_dialog_item (app_chooser, TRUE);
 
1197
+
 
1198
+        if (pref_ask) {
 
1199
+                gtk_app_chooser_button_set_active_custom_item (app_chooser, CUSTOM_ITEM_ASK);
 
1200
+        } else if (pref_ignore) {
 
1201
+                gtk_app_chooser_button_set_active_custom_item (app_chooser, CUSTOM_ITEM_DO_NOTHING);
 
1202
+        } else if (pref_open_folder) {
 
1203
+                gtk_app_chooser_button_set_active_custom_item (app_chooser, CUSTOM_ITEM_OPEN_FOLDER);
 
1204
+        }
 
1205
+
 
1206
+        g_signal_connect (app_chooser, "changed",
 
1207
+                          G_CALLBACK (combo_box_changed_cb), data);
 
1208
+        g_signal_connect (app_chooser, "custom-item-activated",
 
1209
+                          G_CALLBACK (custom_item_activated_cb), data);
 
1210
+
 
1211
+        g_free (content_type);
 
1212
+}
 
1213
+
 
1214
+static gboolean
 
1215
+is_shift_pressed (void)
 
1216
+{
 
1217
+       gboolean ret;
 
1218
+       XkbStateRec state;
 
1219
+       Bool status;
 
1220
+
 
1221
+       ret = FALSE;
 
1222
+
 
1223
+        gdk_error_trap_push ();
 
1224
+       status = XkbGetState (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
 
1225
+                             XkbUseCoreKbd, &state);
 
1226
+        gdk_error_trap_pop_ignored ();
 
1227
+
 
1228
+       if (status == Success) {
 
1229
+               ret = state.mods & ShiftMask;
 
1230
+       }
 
1231
+
 
1232
+       return ret;
 
1233
+}
 
1234
+
 
1235
+enum {
 
1236
+       AUTORUN_DIALOG_RESPONSE_EJECT = 0
 
1237
+};
 
1238
+
 
1239
+static void
 
1240
+gsd_autorun_launch_for_mount (GMount *mount, GAppInfo *app_info)
 
1241
+{
 
1242
+       GFile *root;
 
1243
+       GdkAppLaunchContext *launch_context;
 
1244
+       GError *error;
 
1245
+       gboolean result;
 
1246
+       GList *list;
 
1247
+       gchar *uri_scheme;
 
1248
+       gchar *uri;
 
1249
+
 
1250
+       root = g_mount_get_root (mount);
 
1251
+       list = g_list_append (NULL, root);
 
1252
+
 
1253
+       launch_context = gdk_app_launch_context_new ();
 
1254
+
 
1255
+       error = NULL;
 
1256
+       result = g_app_info_launch (app_info,
 
1257
+                                   list,
 
1258
+                                   G_APP_LAUNCH_CONTEXT (launch_context),
 
1259
+                                   &error);
 
1260
+
 
1261
+       g_object_unref (launch_context);
 
1262
+
 
1263
+       if (!result) {
 
1264
+               if (error->domain == G_IO_ERROR &&
 
1265
+                   error->code == G_IO_ERROR_NOT_SUPPORTED) {
 
1266
+                       uri = g_file_get_uri (root);
 
1267
+                       uri_scheme = g_uri_parse_scheme (uri);
 
1268
+
 
1269
+                       /* FIXME: Present user a dialog to choose another app when the last one failed to handle a file */
 
1270
+                       g_warning ("Cannot open location: %s\n", error->message);
 
1271
+
 
1272
+                       g_free (uri_scheme);
 
1273
+                       g_free (uri);
 
1274
+               } else {
 
1275
+                       g_warning ("Cannot open app: %s\n", error->message);
 
1276
+               }
 
1277
+               g_error_free (error);
 
1278
+       }
 
1279
+
 
1280
+       g_list_free (list);
 
1281
+       g_object_unref (root);
 
1282
+}
 
1283
+
 
1284
+static void autorun_dialog_mount_unmounted (GMount *mount, AutorunDialogData *data);
 
1285
+
 
1286
+static void
 
1287
+autorun_dialog_destroy (AutorunDialogData *data)
 
1288
+{
 
1289
+       g_signal_handlers_disconnect_by_func (G_OBJECT (data->mount),
 
1290
+                                             G_CALLBACK (autorun_dialog_mount_unmounted),
 
1291
+                                             data);
 
1292
+
 
1293
+       gtk_widget_destroy (GTK_WIDGET (data->dialog));
 
1294
+       if (data->selected_app != NULL) {
 
1295
+               g_object_unref (data->selected_app);
 
1296
+       }
 
1297
+       g_object_unref (data->mount);
 
1298
+       g_free (data->x_content_type);
 
1299
+       g_free (data);
 
1300
+}
 
1301
+
 
1302
+static void
 
1303
+autorun_dialog_mount_unmounted (GMount *mount, AutorunDialogData *data)
 
1304
+{
 
1305
+       /* remove the dialog if the media is unmounted */
 
1306
+       autorun_dialog_destroy (data);
 
1307
+}
 
1308
+
 
1309
+static void
 
1310
+unmount_mount_callback (GObject *source_object,
 
1311
+                       GAsyncResult *res,
 
1312
+                       gpointer user_data)
 
1313
+{
 
1314
+       GError *error;
 
1315
+       char *primary;
 
1316
+       gboolean unmounted;
 
1317
+       gboolean should_eject;
 
1318
+       GtkWidget *dialog;
 
1319
+
 
1320
+
 
1321
+       should_eject = user_data != NULL;
 
1322
+
 
1323
+       error = NULL;
 
1324
+       if (should_eject) {
 
1325
+               unmounted = g_mount_eject_with_operation_finish (G_MOUNT (source_object),
 
1326
+                                                                res, &error);
 
1327
+       } else {
 
1328
+               unmounted = g_mount_unmount_with_operation_finish (G_MOUNT (source_object),
 
1329
+                                                                  res, &error);
 
1330
+       }
 
1331
+
 
1332
+       if (! unmounted) {
 
1333
+               if (error->code != G_IO_ERROR_FAILED_HANDLED) {
 
1334
+                       if (should_eject) {
 
1335
+                               primary = g_strdup_printf (_("Unable to eject %p"), source_object);
 
1336
+                       } else {
 
1337
+                               primary = g_strdup_printf (_("Unable to unmount %p"), source_object);
 
1338
+                       }
 
1339
+
 
1340
+                       dialog = gtk_message_dialog_new (NULL,
 
1341
+                                                        0,
 
1342
+                                                        GTK_MESSAGE_INFO,
 
1343
+                                                        GTK_BUTTONS_OK,
 
1344
+                                                        "%s",
 
1345
+                                                        primary);
 
1346
+                       gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
 
1347
+                                                                   "%s",
 
1348
+                                                                   error->message);
 
1349
+
 
1350
+                       gtk_widget_show (GTK_WIDGET (dialog));
 
1351
+                       g_signal_connect (dialog, "response",
 
1352
+                                         G_CALLBACK (gtk_widget_destroy), NULL);
 
1353
+                       g_free (primary);
 
1354
+               }
 
1355
+       }
 
1356
+
 
1357
+       if (error != NULL) {
 
1358
+               g_error_free (error);
 
1359
+       }
 
1360
+}
 
1361
+
 
1362
+static void
 
1363
+do_unmount (GMount *mount, gboolean should_eject, GtkWindow *window)
 
1364
+{
 
1365
+       GMountOperation *mount_op;
 
1366
+
 
1367
+       mount_op = gtk_mount_operation_new (window);
 
1368
+       if (should_eject) {
 
1369
+               g_mount_eject_with_operation (mount,
 
1370
+                                             0,
 
1371
+                                             mount_op,
 
1372
+                                             NULL,
 
1373
+                                             unmount_mount_callback,
 
1374
+                                             (gpointer) 1);
 
1375
+       } else {
 
1376
+               g_mount_unmount_with_operation (mount,
 
1377
+                                               0,
 
1378
+                                               mount_op,
 
1379
+                                               NULL,
 
1380
+                                               unmount_mount_callback,
 
1381
+                                               (gpointer) 0);
 
1382
+       }
 
1383
+       g_object_unref (mount_op);
 
1384
+}
 
1385
+
 
1386
+static void
 
1387
+autorun_dialog_response (GtkDialog *dialog, gint response, AutorunDialogData *data)
 
1388
+{
 
1389
+       switch (response) {
 
1390
+       case AUTORUN_DIALOG_RESPONSE_EJECT:
 
1391
+               do_unmount (data->mount, data->should_eject, GTK_WINDOW (dialog));
 
1392
+               break;
 
1393
+
 
1394
+       case GTK_RESPONSE_NONE:
 
1395
+               /* window was closed */
 
1396
+               break;
 
1397
+       case GTK_RESPONSE_CANCEL:
 
1398
+               break;
 
1399
+       case GTK_RESPONSE_OK:
 
1400
+               /* do the selected action */
 
1401
+
 
1402
+               if (data->remember) {
 
1403
+                       /* make sure we don't ask again */
 
1404
+                       gsd_autorun_set_preferences (data->x_content_type, TRUE, data->selected_ignore, data->selected_open_folder);
 
1405
+                       if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) {
 
1406
+                               g_app_info_set_as_default_for_type (data->selected_app,
 
1407
+                                                                   data->x_content_type,
 
1408
+                                                                   NULL);
 
1409
+                       }
 
1410
+               } else {
 
1411
+                       /* make sure we do ask again */
 
1412
+                       gsd_autorun_set_preferences (data->x_content_type, FALSE, FALSE, FALSE);
 
1413
+               }
 
1414
+
 
1415
+               if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) {
 
1416
+                       gsd_autorun_launch_for_mount (data->mount, data->selected_app);
 
1417
+               } else if (!data->selected_ignore && data->selected_open_folder) {
 
1418
+                       if (data->open_window_func != NULL)
 
1419
+                               data->open_window_func (data->mount, data->user_data);
 
1420
+               }
 
1421
+               break;
 
1422
+       }
 
1423
+
 
1424
+       autorun_dialog_destroy (data);
 
1425
+}
 
1426
+
 
1427
+static void
 
1428
+autorun_always_toggled (GtkToggleButton *togglebutton, AutorunDialogData *data)
 
1429
+{
 
1430
+       data->remember = gtk_toggle_button_get_active (togglebutton);
 
1431
+}
 
1432
+
 
1433
+static gboolean
 
1434
+combo_box_enter_ok (GtkWidget *togglebutton, GdkEventKey *event, GtkDialog *dialog)
 
1435
+{
 
1436
+       if (event->keyval == GDK_KEY_KP_Enter || event->keyval == GDK_KEY_Return) {
 
1437
+               gtk_dialog_response (dialog, GTK_RESPONSE_OK);
 
1438
+               return TRUE;
 
1439
+       }
 
1440
+       return FALSE;
 
1441
+}
 
1442
+
 
1443
+/* returns TRUE if a folder window should be opened */
 
1444
+static gboolean
 
1445
+do_autorun_for_content_type (GMount *mount,
 
1446
+                             const char *x_content_type,
 
1447
+                             GsdAutorunOpenWindow open_window_func,
 
1448
+                             gpointer user_data)
 
1449
+{
 
1450
+       AutorunDialogData *data;
 
1451
+       GtkWidget *dialog;
 
1452
+       GtkWidget *hbox;
 
1453
+       GtkWidget *vbox;
 
1454
+       GtkWidget *label;
 
1455
+       GtkWidget *combo_box;
 
1456
+       GtkWidget *always_check_button;
 
1457
+       GtkWidget *eject_button;
 
1458
+       GtkWidget *image;
 
1459
+       char *markup;
 
1460
+       char *content_description;
 
1461
+       char *mount_name;
 
1462
+       GIcon *icon;
 
1463
+       GdkPixbuf *pixbuf;
 
1464
+       int icon_size;
 
1465
+       gboolean user_forced_dialog;
 
1466
+       gboolean pref_ask;
 
1467
+       gboolean pref_start_app;
 
1468
+       gboolean pref_ignore;
 
1469
+       gboolean pref_open_folder;
 
1470
+       char *media_greeting;
 
1471
+       gboolean ret;
 
1472
+
 
1473
+       ret = FALSE;
 
1474
+       mount_name = NULL;
 
1475
+
 
1476
+       if (g_content_type_is_a (x_content_type, "x-content/win32-software")) {
 
1477
+               /* don't pop up the dialog anyway if the content type says
 
1478
+                * windows software.
 
1479
+                */
 
1480
+               goto out;
 
1481
+       }
 
1482
+
 
1483
+       user_forced_dialog = is_shift_pressed ();
 
1484
+
 
1485
+       gsd_autorun_get_preferences (x_content_type, &pref_start_app, &pref_ignore, &pref_open_folder);
 
1486
+       pref_ask = !pref_start_app && !pref_ignore && !pref_open_folder;
 
1487
+
 
1488
+       if (user_forced_dialog) {
 
1489
+               goto show_dialog;
 
1490
+       }
 
1491
+
 
1492
+       if (!pref_ask && !pref_ignore && !pref_open_folder) {
 
1493
+               GAppInfo *app_info;
 
1494
+               app_info = g_app_info_get_default_for_type (x_content_type, FALSE);
 
1495
+               if (app_info != NULL) {
 
1496
+                       gsd_autorun_launch_for_mount (mount, app_info);
 
1497
+               }
 
1498
+               goto out;
 
1499
+       }
 
1500
+
 
1501
+       if (pref_open_folder) {
 
1502
+               ret = TRUE;
 
1503
+               goto out;
 
1504
+       }
 
1505
+
 
1506
+       if (pref_ignore) {
 
1507
+               goto out;
 
1508
+       }
 
1509
+
 
1510
+show_dialog:
 
1511
+
 
1512
+       mount_name = g_mount_get_name (mount);
 
1513
+
 
1514
+       dialog = gtk_dialog_new ();
 
1515
+
 
1516
+       hbox = gtk_hbox_new (FALSE, 12);
 
1517
+       gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, TRUE, TRUE, 0);
 
1518
+       gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
 
1519
+
 
1520
+       icon = g_mount_get_icon (mount);
 
1521
+       icon_size = get_icon_size_for_stock_size (GTK_ICON_SIZE_DIALOG);
 
1522
+       image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
 
1523
+       pixbuf = render_icon (icon, icon_size);
 
1524
+       gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
 
1525
+       gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0);
 
1526
+       /* also use the icon on the dialog */
 
1527
+       gtk_window_set_title (GTK_WINDOW (dialog), mount_name);
 
1528
+       gtk_window_set_icon (GTK_WINDOW (dialog), pixbuf);
 
1529
+       gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
 
1530
+       g_object_unref (icon);
 
1531
+       if (pixbuf) {
 
1532
+               g_object_unref (pixbuf);
 
1533
+       }
 
1534
+       vbox = gtk_vbox_new (FALSE, 12);
 
1535
+       gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
 
1536
+
 
1537
+       label = gtk_label_new (NULL);
 
1538
+
 
1539
+
 
1540
+       /* Customize greeting for well-known x-content types */
 
1541
+       if (strcmp (x_content_type, "x-content/audio-cdda") == 0) {
 
1542
+               media_greeting = _("You have just inserted an Audio CD.");
 
1543
+       } else if (strcmp (x_content_type, "x-content/audio-dvd") == 0) {
 
1544
+               media_greeting = _("You have just inserted an Audio DVD.");
 
1545
+       } else if (strcmp (x_content_type, "x-content/video-dvd") == 0) {
 
1546
+               media_greeting = _("You have just inserted a Video DVD.");
 
1547
+       } else if (strcmp (x_content_type, "x-content/video-vcd") == 0) {
 
1548
+               media_greeting = _("You have just inserted a Video CD.");
 
1549
+       } else if (strcmp (x_content_type, "x-content/video-svcd") == 0) {
 
1550
+               media_greeting = _("You have just inserted a Super Video CD.");
 
1551
+       } else if (strcmp (x_content_type, "x-content/blank-cd") == 0) {
 
1552
+               media_greeting = _("You have just inserted a blank CD.");
 
1553
+       } else if (strcmp (x_content_type, "x-content/blank-dvd") == 0) {
 
1554
+               media_greeting = _("You have just inserted a blank DVD.");
 
1555
+       } else if (strcmp (x_content_type, "x-content/blank-cd") == 0) {
 
1556
+               media_greeting = _("You have just inserted a blank Blu-Ray disc.");
 
1557
+       } else if (strcmp (x_content_type, "x-content/blank-cd") == 0) {
 
1558
+               media_greeting = _("You have just inserted a blank HD DVD.");
 
1559
+       } else if (strcmp (x_content_type, "x-content/image-photocd") == 0) {
 
1560
+               media_greeting = _("You have just inserted a Photo CD.");
 
1561
+       } else if (strcmp (x_content_type, "x-content/image-picturecd") == 0) {
 
1562
+               media_greeting = _("You have just inserted a Picture CD.");
 
1563
+       } else if (strcmp (x_content_type, "x-content/image-dcf") == 0) {
 
1564
+               media_greeting = _("You have just inserted a medium with digital photos.");
 
1565
+       } else if (strcmp (x_content_type, "x-content/audio-player") == 0) {
 
1566
+               media_greeting = _("You have just inserted a digital audio player.");
 
1567
+       } else if (g_content_type_is_a (x_content_type, "x-content/software")) {
 
1568
+               media_greeting = _("You have just inserted a medium with software intended to be automatically started.");
 
1569
+       } else {
 
1570
+               /* fallback to generic greeting */
 
1571
+               media_greeting = _("You have just inserted a medium.");
 
1572
+       }
 
1573
+       markup = g_strdup_printf ("<big><b>%s %s</b></big>", media_greeting, _("Choose what application to launch."));
 
1574
+       gtk_label_set_markup (GTK_LABEL (label), markup);
 
1575
+       g_free (markup);
 
1576
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 
1577
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 
1578
+       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
 
1579
+
 
1580
+       label = gtk_label_new (NULL);
 
1581
+       content_description = g_content_type_get_description (x_content_type);
 
1582
+       markup = g_strdup_printf (_("Select how to open \"%s\" and whether to perform this action in the future for other media of type \"%s\"."), mount_name, content_description);
 
1583
+       g_free (content_description);
 
1584
+       gtk_label_set_markup (GTK_LABEL (label), markup);
 
1585
+       g_free (markup);
 
1586
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 
1587
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 
1588
+       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
 
1589
+
 
1590
+       data = g_new0 (AutorunDialogData, 1);
 
1591
+       data->dialog = dialog;
 
1592
+       data->mount = g_object_ref (mount);
 
1593
+       data->remember = !pref_ask;
 
1594
+       data->selected_ignore = pref_ignore;
 
1595
+       data->x_content_type = g_strdup (x_content_type);
 
1596
+       data->selected_app = g_app_info_get_default_for_type (x_content_type, FALSE);
 
1597
+       data->open_window_func = open_window_func;
 
1598
+       data->user_data = user_data;
 
1599
+
 
1600
+       combo_box = gtk_app_chooser_button_new (x_content_type);
 
1601
+       prepare_combo_box (combo_box, data);
 
1602
+       g_signal_connect (G_OBJECT (combo_box),
 
1603
+                         "key-press-event",
 
1604
+                         G_CALLBACK (combo_box_enter_ok),
 
1605
+                         dialog);
 
1606
+
 
1607
+       gtk_box_pack_start (GTK_BOX (vbox), combo_box, TRUE, TRUE, 0);
 
1608
+
 
1609
+       always_check_button = gtk_check_button_new_with_mnemonic (_("_Always perform this action"));
 
1610
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (always_check_button), data->remember);
 
1611
+       g_signal_connect (G_OBJECT (always_check_button),
 
1612
+                         "toggled",
 
1613
+                         G_CALLBACK (autorun_always_toggled),
 
1614
+                         data);
 
1615
+       gtk_box_pack_start (GTK_BOX (vbox), always_check_button, TRUE, TRUE, 0);
 
1616
+
 
1617
+       gtk_dialog_add_buttons (GTK_DIALOG (dialog),
 
1618
+                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
1619
+                               GTK_STOCK_OK, GTK_RESPONSE_OK,
 
1620
+                               NULL);
 
1621
+       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
1622
+
 
1623
+       if (g_mount_can_eject (mount)) {
 
1624
+               GtkWidget *eject_image;
 
1625
+               eject_button = gtk_button_new_with_mnemonic (_("_Eject"));
 
1626
+               eject_image = gtk_image_new_from_icon_name ("media-eject", GTK_ICON_SIZE_BUTTON);
 
1627
+               gtk_button_set_image (GTK_BUTTON (eject_button), eject_image);
 
1628
+               data->should_eject = TRUE;
 
1629
+       } else {
 
1630
+               eject_button = gtk_button_new_with_mnemonic (_("_Unmount"));
 
1631
+               data->should_eject = FALSE;
 
1632
+       }
 
1633
+       gtk_dialog_add_action_widget (GTK_DIALOG (dialog), eject_button, AUTORUN_DIALOG_RESPONSE_EJECT);
 
1634
+       gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog))), eject_button, TRUE);
 
1635
+
 
1636
+       /* show the dialog */
 
1637
+       gtk_widget_show_all (dialog);
 
1638
+
 
1639
+       g_signal_connect (G_OBJECT (dialog),
 
1640
+                         "response",
 
1641
+                         G_CALLBACK (autorun_dialog_response),
 
1642
+                         data);
 
1643
+
 
1644
+       g_signal_connect (G_OBJECT (data->mount),
 
1645
+                         "unmounted",
 
1646
+                         G_CALLBACK (autorun_dialog_mount_unmounted),
 
1647
+                         data);
 
1648
+
 
1649
+out:
 
1650
+       g_free (mount_name);
 
1651
+       return ret;
 
1652
+}
 
1653
+
 
1654
+typedef struct {
 
1655
+       GMount *mount;
 
1656
+       GsdAutorunOpenWindow open_window_func;
 
1657
+       gpointer user_data;
 
1658
+       GSettings *settings;
 
1659
+} AutorunData;
 
1660
+
 
1661
+static void
 
1662
+autorun_guessed_content_type_callback (GObject *source_object,
 
1663
+                                      GAsyncResult *res,
 
1664
+                                      gpointer user_data)
 
1665
+{
 
1666
+       GError *error;
 
1667
+       char **guessed_content_type;
 
1668
+       AutorunData *data = user_data;
 
1669
+       gboolean open_folder;
 
1670
+
 
1671
+       open_folder = FALSE;
 
1672
+
 
1673
+       error = NULL;
 
1674
+       guessed_content_type = g_mount_guess_content_type_finish (G_MOUNT (source_object), res, &error);
 
1675
+       g_object_set_data_full (source_object,
 
1676
+                               "gsd-content-type-cache",
 
1677
+                               g_strdupv (guessed_content_type),
 
1678
+                               (GDestroyNotify)g_strfreev);
 
1679
+       if (error != NULL) {
 
1680
+               g_warning ("Unable to guess content type for mount: %s", error->message);
 
1681
+               g_error_free (error);
 
1682
+       } else {
 
1683
+               if (guessed_content_type != NULL && g_strv_length (guessed_content_type) > 0) {
 
1684
+                       int n;
 
1685
+                       for (n = 0; guessed_content_type[n] != NULL; n++) {
 
1686
+                               if (do_autorun_for_content_type (data->mount, guessed_content_type[n],
 
1687
+                                                                data->open_window_func, data->user_data)) {
 
1688
+                                       open_folder = TRUE;
 
1689
+                               }
 
1690
+                       }
 
1691
+                       g_strfreev (guessed_content_type);
 
1692
+               } else {
 
1693
+                       if (g_settings_get_boolean (data->settings, "automount-open")) {
 
1694
+                               open_folder = TRUE;
 
1695
+                       }
 
1696
+               }
 
1697
+       }
 
1698
+
 
1699
+       /* only open the folder once.. */
 
1700
+       if (open_folder && data->open_window_func != NULL) {
 
1701
+               data->open_window_func (data->mount, data->user_data);
 
1702
+       }
 
1703
+
 
1704
+       g_object_unref (data->mount);
 
1705
+       g_object_unref (data->settings);
 
1706
+       g_free (data);
 
1707
+}
 
1708
+
 
1709
+void
 
1710
+gsd_autorun (GMount *mount,
 
1711
+             GSettings *settings,
 
1712
+             GsdAutorunOpenWindow open_window_func,
 
1713
+             gpointer user_data)
 
1714
+{
 
1715
+       AutorunData *data;
 
1716
+
 
1717
+       if (!should_autorun_mount (mount) ||
 
1718
+           g_settings_get_boolean (settings, "autorun-never")) {
 
1719
+               return;
 
1720
+       }
 
1721
+
 
1722
+       data = g_new0 (AutorunData, 1);
 
1723
+       data->mount = g_object_ref (mount);
 
1724
+       data->open_window_func = open_window_func;
 
1725
+       data->user_data = user_data;
 
1726
+       data->settings = g_object_ref (settings);
 
1727
+
 
1728
+       g_mount_guess_content_type (mount,
 
1729
+                                   FALSE,
 
1730
+                                   NULL,
 
1731
+                                   autorun_guessed_content_type_callback,
 
1732
+                                   data);
 
1733
+}
 
1734
+
 
1735
+static gboolean
 
1736
+remove_allow_volume (gpointer data)
 
1737
+{
 
1738
+       GVolume *volume = data;
 
1739
+
 
1740
+       g_object_set_data (G_OBJECT (volume), "gsd-allow-autorun", NULL);
 
1741
+       return FALSE;
 
1742
+}
 
1743
+
 
1744
+void
 
1745
+gsd_allow_autorun_for_volume (GVolume *volume)
 
1746
+{
 
1747
+       g_object_set_data (G_OBJECT (volume), "gsd-allow-autorun", GINT_TO_POINTER (1));
 
1748
+}
 
1749
+
 
1750
+#define INHIBIT_AUTORUN_SECONDS 10
 
1751
+
 
1752
+void
 
1753
+gsd_allow_autorun_for_volume_finish (GVolume *volume)
 
1754
+{
 
1755
+       if (g_object_get_data (G_OBJECT (volume), "gsd-allow-autorun") != NULL) {
 
1756
+               g_timeout_add_seconds_full (0,
 
1757
+                                           INHIBIT_AUTORUN_SECONDS,
 
1758
+                                           remove_allow_volume,
 
1759
+                                           g_object_ref (volume),
 
1760
+                                           g_object_unref);
 
1761
+       }
 
1762
+}
 
1763
+
 
1764
+static gboolean
 
1765
+should_skip_native_mount_root (GFile *root)
 
1766
+{
 
1767
+       char *path;
 
1768
+       gboolean should_skip;
 
1769
+
 
1770
+       /* skip any mounts in hidden directory hierarchies */
 
1771
+       path = g_file_get_path (root);
 
1772
+       should_skip = strstr (path, "/.") != NULL;
 
1773
+       g_free (path);
 
1774
+
 
1775
+       return should_skip;
 
1776
+}
 
1777
+
 
1778
+static gboolean
 
1779
+should_autorun_mount (GMount *mount)
 
1780
+{
 
1781
+       GFile *root;
 
1782
+       GVolume *enclosing_volume;
 
1783
+       gboolean ignore_autorun;
 
1784
+
 
1785
+       ignore_autorun = TRUE;
 
1786
+       enclosing_volume = g_mount_get_volume (mount);
 
1787
+       if (enclosing_volume != NULL) {
 
1788
+               if (g_object_get_data (G_OBJECT (enclosing_volume), "gsd-allow-autorun") != NULL) {
 
1789
+                       ignore_autorun = FALSE;
 
1790
+                       g_object_set_data (G_OBJECT (enclosing_volume), "gsd-allow-autorun", NULL);
 
1791
+               }
 
1792
+       }
 
1793
+
 
1794
+       if (ignore_autorun) {
 
1795
+               if (enclosing_volume != NULL) {
 
1796
+                       g_object_unref (enclosing_volume);
 
1797
+               }
 
1798
+               return FALSE;
 
1799
+       }
 
1800
+
 
1801
+       root = g_mount_get_root (mount);
 
1802
+
 
1803
+       /* only do autorun on local files or files where g_volume_should_automount() returns TRUE */
 
1804
+       ignore_autorun = TRUE;
 
1805
+       if ((g_file_is_native (root) && !should_skip_native_mount_root (root)) ||
 
1806
+           (enclosing_volume != NULL && g_volume_should_automount (enclosing_volume))) {
 
1807
+               ignore_autorun = FALSE;
 
1808
+       }
 
1809
+       if (enclosing_volume != NULL) {
 
1810
+               g_object_unref (enclosing_volume);
 
1811
+       }
 
1812
+       g_object_unref (root);
 
1813
+
 
1814
+       return !ignore_autorun;
 
1815
+}
 
1816
Index: gnome-settings-daemon-3.8.5/plugins/automount/gsd-autorun.h
 
1817
===================================================================
 
1818
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
1819
+++ gnome-settings-daemon-3.8.5/plugins/automount/gsd-autorun.h 2013-11-12 16:32:41.738469452 +1300
 
1820
@@ -0,0 +1,53 @@
 
1821
+/*
 
1822
+ * gsd-automount.h:helpers for automounting hotplugged volumes
 
1823
+ *
 
1824
+ * Copyright (C) 2008 Red Hat, Inc.
 
1825
+ *
 
1826
+ * Nautilus is free software; you can redistribute it and/or modify
 
1827
+ * it under the terms of the GNU General Public License as published by
 
1828
+ * the Free Software Foundation; either version 2 of the License, or
 
1829
+ * (at your option) any later version.
 
1830
+ *
 
1831
+ * This program is distributed in the hope that it will be useful,
 
1832
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
1833
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
1834
+ * GNU General Public License for more details.
 
1835
+ *
 
1836
+ * You should have received a copy of the GNU General Public License
 
1837
+ * along with this program; if not, write to the Free Software
 
1838
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
1839
+ *
 
1840
+ * Authors: David Zeuthen <davidz@redhat.com>
 
1841
+ *          Cosimo Cecchi <cosimoc@redhat.com>
 
1842
+ */
 
1843
+
 
1844
+/* TODO:
 
1845
+ *
 
1846
+ * - unmount all the media we've automounted on shutdown
 
1847
+ * - finish x-content / * types
 
1848
+ *  - finalize the semi-spec
 
1849
+ *  - add probing/sniffing code
 
1850
+ * - implement missing features
 
1851
+ *  - "Open Folder when mounted"
 
1852
+ *  - Autorun spec (e.g. $ROOT/.autostart)
 
1853
+ *
 
1854
+ */
 
1855
+
 
1856
+#ifndef __GSD_AUTORUN_H__
 
1857
+#define __GSD_AUTORUN_H__
 
1858
+
 
1859
+#include <gtk/gtk.h>
 
1860
+#include <gio/gio.h>
 
1861
+
 
1862
+typedef void (*GsdAutorunOpenWindow) (GMount *mount,
 
1863
+                                     gpointer user_data);
 
1864
+
 
1865
+void gsd_autorun (GMount *mount,
 
1866
+                 GSettings *settings,
 
1867
+                 GsdAutorunOpenWindow open_window_func,
 
1868
+                 gpointer user_data);
 
1869
+
 
1870
+void gsd_allow_autorun_for_volume (GVolume *volume);
 
1871
+void gsd_allow_autorun_for_volume_finish (GVolume *volume);
 
1872
+
 
1873
+#endif /* __GSD_AUTORUN_H__ */
 
1874
Index: gnome-settings-daemon-3.8.5/po/POTFILES.in
 
1875
===================================================================
 
1876
--- gnome-settings-daemon-3.8.5.orig/po/POTFILES.in     2013-11-12 16:32:41.742469452 +1300
 
1877
+++ gnome-settings-daemon-3.8.5/po/POTFILES.in  2013-11-12 16:32:41.738469452 +1300
 
1878
@@ -18,6 +18,9 @@
 
1879
 [type: gettext/ini]plugins/a11y-keyboard/a11y-keyboard.gnome-settings-plugin.in
 
1880
 plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c
 
1881
 [type: gettext/ini]plugins/a11y-settings/a11y-settings.gnome-settings-plugin.in
 
1882
+plugins/automount/gnome-fallback-mount-helper.desktop.in.in
 
1883
+plugins/automount/gsd-automount-manager.c
 
1884
+plugins/automount/gsd-autorun.c
 
1885
 [type: gettext/ini]plugins/background/background.gnome-settings-plugin.in
 
1886
 [type: gettext/ini]plugins/clipboard/clipboard.gnome-settings-plugin.in
 
1887
 [type: gettext/ini]plugins/color/color.gnome-settings-plugin.in