Skip to content
Permalink
Browse files

monitor: watch for removal of non-native mounts on GVolumeMonitor

Fix #1066 "Caja caches folders from usb drives/disk"

Nowadays, we rely on G_FILE_MONITOR_EVENT_UNMOUNTED to be emitted when a
mount disappears, since we already monitor the directory, in order to
switch the view to a different location.
Since non-native mounts very likely won't have file monitoring though,
we're not going to receive such events in that case, and fail to
redirect the view as a consequence.
This patch fixes it by listening to the mount-removed signal on
GVolumeMonitor when a monitor is requested for a non-native mount, and
emulating a file removal in that case.

Backport  Nautilus commit gitlab.gnome.org/GNOME/nautilus/commit/3891241ba760c59d284b7579dbd340651c8d4d29

note that caja_get_mounted_mount_for_root had to be added, while the equivalent Nautilus function was from a prior commit
  • Loading branch information...
lukefromdc committed Oct 16, 2018
1 parent 09146ca commit 8fff655552209fd181f9608d02d0f72660b10768
Showing with 96 additions and 10 deletions.
  1. +42 −0 libcaja-private/caja-file-utilities.c
  2. +1 −0 libcaja-private/caja-file-utilities.h
  3. +53 −10 libcaja-private/caja-monitor.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
*
@@ -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);

@@ -34,6 +34,9 @@
struct CajaMonitor
{
GFileMonitor *monitor;
GVolumeMonitor *volume_monitor;
GMount *mount;
GFile *location;
};

gboolean
@@ -72,6 +75,27 @@ call_consume_changes_idle_cb (gpointer not_used)
return FALSE;
}

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,
@@ -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);
}

0 comments on commit 8fff655

Please sign in to comment.
You can’t perform that action at this time.