summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcaja-private/caja-file-utilities.c42
-rw-r--r--libcaja-private/caja-file-utilities.h1
-rw-r--r--libcaja-private/caja-monitor.c63
3 files changed, 96 insertions, 10 deletions
diff --git a/libcaja-private/caja-file-utilities.c b/libcaja-private/caja-file-utilities.c
index 237f85d7..46f90b0a 100644
--- a/libcaja-private/caja-file-utilities.c
+++ b/libcaja-private/caja-file-utilities.c
@@ -756,6 +756,48 @@ caja_is_desktop_directory (GFile *dir)
return g_file_equal (dir, desktop_dir);
}
+GMount *
+caja_get_mounted_mount_for_root (GFile *location)
+{
+ GVolumeMonitor *volume_monitor;
+ GList *mounts;
+ GList *l;
+ GMount *mount;
+ GMount *result = NULL;
+ GFile *root = NULL;
+ GFile *default_location = NULL;
+
+ volume_monitor = g_volume_monitor_get ();
+ mounts = g_volume_monitor_get_mounts (volume_monitor);
+
+ for (l = mounts; l != NULL; l = l->next) {
+ mount = l->data;
+
+ if (g_mount_is_shadowed (mount)) {
+ continue;
+ }
+
+ root = g_mount_get_root (mount);
+ if (g_file_equal (location, root)) {
+ result = g_object_ref (mount);
+ break;
+ }
+
+ default_location = g_mount_get_default_location (mount);
+ if (!g_file_equal (default_location, root) &&
+ g_file_equal (location, default_location)) {
+ result = g_object_ref (mount);
+ break;
+ }
+ }
+
+ g_clear_object (&root);
+ g_clear_object (&default_location);
+ g_list_free_full (mounts, g_object_unref);
+
+ return result;
+}
+
/**
* caja_get_pixmap_directory
*
diff --git a/libcaja-private/caja-file-utilities.h b/libcaja-private/caja-file-utilities.h
index 370cec02..2306601f 100644
--- a/libcaja-private/caja-file-utilities.h
+++ b/libcaja-private/caja-file-utilities.h
@@ -47,6 +47,7 @@ gboolean caja_is_desktop_directory (GFile *dir);
gboolean caja_is_home_directory (GFile *dir);
gboolean caja_is_home_directory_file (GFile *dir,
const char *filename);
+GMount * caja_get_mounted_mount_for_root (GFile *location);
gboolean caja_is_in_system_dir (GFile *location);
char * caja_get_pixmap_directory (void);
diff --git a/libcaja-private/caja-monitor.c b/libcaja-private/caja-monitor.c
index 0434dfe2..73d18f36 100644
--- a/libcaja-private/caja-monitor.c
+++ b/libcaja-private/caja-monitor.c
@@ -34,6 +34,9 @@
struct CajaMonitor
{
GFileMonitor *monitor;
+ GVolumeMonitor *volume_monitor;
+ GMount *mount;
+ GFile *location;
};
gboolean
@@ -73,6 +76,27 @@ call_consume_changes_idle_cb (gpointer not_used)
}
static void
+schedule_call_consume_changes (void)
+{
+ if (call_consume_changes_idle_id == 0) {
+ call_consume_changes_idle_id =
+ g_idle_add (call_consume_changes_idle_cb, NULL);
+ }
+}
+
+static void
+mount_removed (GVolumeMonitor *volume_monitor,
+ GMount *mount,
+ gpointer user_data)
+{
+ CajaMonitor *monitor = user_data;
+ if (mount == monitor->mount) {
+ caja_file_changes_queue_file_removed (monitor->location);
+ schedule_call_consume_changes ();
+ }
+}
+
+static void
dir_changed (GFileMonitor* monitor,
GFile *child,
GFile *other_file,
@@ -115,12 +139,7 @@ dir_changed (GFileMonitor* monitor,
g_free (uri);
g_free (to_uri);
-
- if (call_consume_changes_idle_id == 0)
- {
- call_consume_changes_idle_id =
- g_idle_add (call_consume_changes_idle_cb, NULL);
- }
+ schedule_call_consume_changes ();
}
CajaMonitor *
@@ -129,16 +148,33 @@ caja_monitor_directory (GFile *location)
GFileMonitor *dir_monitor;
CajaMonitor *ret;
+ ret = g_new0 (CajaMonitor, 1);
dir_monitor = g_file_monitor_directory (location, G_FILE_MONITOR_WATCH_MOUNTS, NULL, NULL);
- ret = g_new0 (CajaMonitor, 1);
- ret->monitor = dir_monitor;
+ if (dir_monitor != NULL) {
+ ret->monitor = dir_monitor;
+ }
- if (ret->monitor)
- {
+ else if (!g_file_is_native (location)) {
+ ret->mount = caja_get_mounted_mount_for_root (location);
+ ret->location = g_object_ref (location);
+ ret->volume_monitor = g_volume_monitor_get ();
+ }
+
+ if (ret->monitor != NULL) {
+ g_signal_connect (ret->monitor, "changed",
+ G_CALLBACK (dir_changed), ret);
+ }
+
+ if (ret->monitor) {
g_signal_connect (ret->monitor, "changed", (GCallback)dir_changed, ret);
}
+ if (ret->volume_monitor != NULL) {
+ g_signal_connect (ret->volume_monitor, "mount-removed",
+ G_CALLBACK (mount_removed), ret);
+ }
+
/* We return a monitor even on failure, so we can avoid later trying again */
return ret;
}
@@ -153,5 +189,12 @@ caja_monitor_cancel (CajaMonitor *monitor)
g_object_unref (monitor->monitor);
}
+ if (monitor->volume_monitor != NULL) {
+ g_signal_handlers_disconnect_by_func (monitor->volume_monitor, mount_removed, monitor);
+ g_object_unref (monitor->volume_monitor);
+ }
+
+ g_clear_object (&monitor->location);
+ g_clear_object (&monitor->mount);
g_free (monitor);
}