diff options
Diffstat (limited to 'src/caja-application.c')
-rw-r--r-- | src/caja-application.c | 238 |
1 files changed, 232 insertions, 6 deletions
diff --git a/src/caja-application.c b/src/caja-application.c index b7199725..e4d2d973 100644 --- a/src/caja-application.c +++ b/src/caja-application.c @@ -78,8 +78,6 @@ #define MATE_DESKTOP_USE_UNSTABLE_API #include <libmate-desktop/mate-bg.h> -#include "glibcompat.h" /* for g_list_free_full */ - enum { COMMAND_0, /* unused: 0 is an invalid command */ @@ -122,7 +120,10 @@ static void mount_added_callback (GVolumeMonitor *mo static void volume_added_callback (GVolumeMonitor *monitor, GVolume *volume, CajaApplication *application); -static void drive_connected_callback (GVolumeMonitor *monitor, +static void volume_removed_callback (GVolumeMonitor *monitor, + GVolume *volume, + CajaApplication *application); + static void drive_connected_callback (GVolumeMonitor *monitor, GDrive *drive, CajaApplication *application); static void drive_listen_for_eject_button (GDrive *drive, @@ -362,7 +363,18 @@ caja_application_finalize (GObject *object) g_object_unref (application->unique_app); - if (application->automount_idle_id != 0) + if (application->ss_watch_id > 0) + { + g_bus_unwatch_name (application->ss_watch_id); + } + + if (application->volume_queue != NULL) + { + g_list_free_full (application->volume_queue, g_object_unref); + application->volume_queue = NULL; + } + + if (application->automount_idle_id != 0) { g_source_remove (application->automount_idle_id); application->automount_idle_id = 0; @@ -374,6 +386,12 @@ caja_application_finalize (GObject *object) fdb_manager = NULL; } + if (application->ss_proxy != NULL) + { + g_object_unref (application->ss_proxy); + application->ss_proxy = NULL; + } + G_OBJECT_CLASS (caja_application_parent_class)->finalize (object); } @@ -554,6 +572,180 @@ out: } static void +check_volume_queue (CajaApplication *application) +{ + GList *l, *next; + GVolume *volume; + + l = application->volume_queue; + + if (application->screensaver_active) + { + return; + } + + while (l != NULL) { + volume = l->data; + next = l->next; + + caja_file_operations_mount_volume (NULL, volume, TRUE); + application->volume_queue = + g_list_remove (application->volume_queue, volume); + + g_object_unref (volume); + l = next; + } + + application->volume_queue = NULL; +} + +#define SCREENSAVER_NAME "org.mate.ScreenSaver" +#define SCREENSAVER_PATH "/org/mate/ScreenSaver" +#define SCREENSAVER_INTERFACE "org.mate.ScreenSaver" + +static void +screensaver_signal_callback (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + CajaApplication *application = user_data; + + if (g_strcmp0 (signal_name, "ActiveChanged") == 0) + { + g_variant_get (parameters, "(b)", &application->screensaver_active); + g_debug ("Screensaver active changed to %d", application->screensaver_active); + + check_volume_queue (application); + } +} + +static void +screensaver_get_active_ready_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CajaApplication *application = user_data; + GDBusProxy *proxy = application->ss_proxy; + GVariant *result; + GError *error = NULL; + + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + + if (error != NULL) { + g_warning ("Can't call GetActive() on the ScreenSaver object: %s", + error->message); + g_error_free (error); + + return; + } + + g_variant_get (result, "(b)", &application->screensaver_active); + g_variant_unref (result); + + g_debug ("Screensaver GetActive() returned %d", application->screensaver_active); +} + +static void +screensaver_proxy_ready_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CajaApplication *application = user_data; + GError *error = NULL; + GDBusProxy *ss_proxy; + + ss_proxy = g_dbus_proxy_new_finish (res, &error); + + if (error != NULL) + { + g_warning ("Can't get proxy for the ScreenSaver object: %s", + error->message); + g_error_free (error); + + return; + } + + g_debug ("ScreenSaver proxy ready"); + + application->ss_proxy = ss_proxy; + + g_signal_connect (ss_proxy, "g-signal", + G_CALLBACK (screensaver_signal_callback), application); + + g_dbus_proxy_call (ss_proxy, + "GetActive", + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + screensaver_get_active_ready_cb, + application); +} + +static void +screensaver_appeared_callback (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + CajaApplication *application = user_data; + + g_debug ("ScreenSaver name appeared"); + + application->screensaver_active = FALSE; + + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + name, + SCREENSAVER_PATH, + SCREENSAVER_INTERFACE, + NULL, + screensaver_proxy_ready_cb, + application); +} + +static void +screensaver_vanished_callback (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + CajaApplication *application = user_data; + + g_debug ("ScreenSaver name vanished"); + + application->screensaver_active = FALSE; + g_object_unref (&application->ss_proxy); + + /* in this case force a clear of the volume queue, without + * mounting them. + */ + if (application->volume_queue != NULL) + { + g_list_free_full (application->volume_queue, g_object_unref); + application->volume_queue = NULL; + } +} + +static void +do_initialize_screensaver (CajaApplication *application) +{ + application->ss_watch_id = + g_bus_watch_name (G_BUS_TYPE_SESSION, + SCREENSAVER_NAME, + G_BUS_NAME_WATCHER_FLAGS_NONE, + screensaver_appeared_callback, + screensaver_vanished_callback, + application, + NULL); +} + + +static void do_upgrades_once (CajaApplication *application, gboolean no_desktop) { @@ -601,7 +793,11 @@ finish_startup (CajaApplication *application, /* Initialize the desktop link monitor singleton */ caja_desktop_link_monitor_get (); - /* Watch for mounts so we can restore open windows This used + /* Initialize MATE screen saver listener to control automount + * permission */ + do_initialize_screensaver (application); + + /* Watch for mounts so we can restore open windows This used * to be for showing new window on mount, but is not used * anymore */ @@ -616,6 +812,8 @@ finish_startup (CajaApplication *application, G_CALLBACK (mount_added_callback), application, 0); g_signal_connect_object (application->volume_monitor, "volume_added", G_CALLBACK (volume_added_callback), application, 0); + g_signal_connect_object (application->volume_monitor, "volume_removed", + G_CALLBACK (volume_removed_callback), application, 0); g_signal_connect_object (application->volume_monitor, "drive_connected", G_CALLBACK (drive_connected_callback), application, 0); @@ -1477,6 +1675,34 @@ window_can_be_closed (CajaWindow *window) } static void +check_screen_lock_and_mount (CajaApplication *application, + GVolume *volume) +{ + if (application->screensaver_active) + { + /* queue the volume, to mount it after the screensaver state changed */ + g_debug ("Queuing volume %p", volume); + application->volume_queue = g_list_prepend (application->volume_queue, + g_object_ref (volume)); + } else { + /* mount it immediately */ + caja_file_operations_mount_volume (NULL, volume, TRUE); + } +} + +static void +volume_removed_callback (GVolumeMonitor *monitor, + GVolume *volume, + CajaApplication *application) +{ + g_debug ("Volume %p removed, removing from the queue", volume); + + /* clear it from the queue, if present */ + application->volume_queue = + g_list_remove (application->volume_queue, volume); +} + +static void volume_added_callback (GVolumeMonitor *monitor, GVolume *volume, CajaApplication *application) @@ -1485,7 +1711,7 @@ volume_added_callback (GVolumeMonitor *monitor, g_volume_should_automount (volume) && g_volume_can_mount (volume)) { - caja_file_operations_mount_volume (NULL, volume, TRUE); + check_screen_lock_and_mount (application, volume); } else { |