Skip to content

Commit 8fff655

Browse files
committed
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
1 parent 09146ca commit 8fff655

File tree

3 files changed

+96
-10
lines changed

3 files changed

+96
-10
lines changed

libcaja-private/caja-file-utilities.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,48 @@ caja_is_desktop_directory (GFile *dir)
756756
return g_file_equal (dir, desktop_dir);
757757
}
758758

759+
GMount *
760+
caja_get_mounted_mount_for_root (GFile *location)
761+
{
762+
GVolumeMonitor *volume_monitor;
763+
GList *mounts;
764+
GList *l;
765+
GMount *mount;
766+
GMount *result = NULL;
767+
GFile *root = NULL;
768+
GFile *default_location = NULL;
769+
770+
volume_monitor = g_volume_monitor_get ();
771+
mounts = g_volume_monitor_get_mounts (volume_monitor);
772+
773+
for (l = mounts; l != NULL; l = l->next) {
774+
mount = l->data;
775+
776+
if (g_mount_is_shadowed (mount)) {
777+
continue;
778+
}
779+
780+
root = g_mount_get_root (mount);
781+
if (g_file_equal (location, root)) {
782+
result = g_object_ref (mount);
783+
break;
784+
}
785+
786+
default_location = g_mount_get_default_location (mount);
787+
if (!g_file_equal (default_location, root) &&
788+
g_file_equal (location, default_location)) {
789+
result = g_object_ref (mount);
790+
break;
791+
}
792+
}
793+
794+
g_clear_object (&root);
795+
g_clear_object (&default_location);
796+
g_list_free_full (mounts, g_object_unref);
797+
798+
return result;
799+
}
800+
759801
/**
760802
* caja_get_pixmap_directory
761803
*

libcaja-private/caja-file-utilities.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ gboolean caja_is_desktop_directory (GFile *dir);
4747
gboolean caja_is_home_directory (GFile *dir);
4848
gboolean caja_is_home_directory_file (GFile *dir,
4949
const char *filename);
50+
GMount * caja_get_mounted_mount_for_root (GFile *location);
5051
gboolean caja_is_in_system_dir (GFile *location);
5152
char * caja_get_pixmap_directory (void);
5253

libcaja-private/caja-monitor.c

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
struct CajaMonitor
3535
{
3636
GFileMonitor *monitor;
37+
GVolumeMonitor *volume_monitor;
38+
GMount *mount;
39+
GFile *location;
3740
};
3841

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

78+
static void
79+
schedule_call_consume_changes (void)
80+
{
81+
if (call_consume_changes_idle_id == 0) {
82+
call_consume_changes_idle_id =
83+
g_idle_add (call_consume_changes_idle_cb, NULL);
84+
}
85+
}
86+
87+
static void
88+
mount_removed (GVolumeMonitor *volume_monitor,
89+
GMount *mount,
90+
gpointer user_data)
91+
{
92+
CajaMonitor *monitor = user_data;
93+
if (mount == monitor->mount) {
94+
caja_file_changes_queue_file_removed (monitor->location);
95+
schedule_call_consume_changes ();
96+
}
97+
}
98+
7599
static void
76100
dir_changed (GFileMonitor* monitor,
77101
GFile *child,
@@ -115,12 +139,7 @@ dir_changed (GFileMonitor* monitor,
115139

116140
g_free (uri);
117141
g_free (to_uri);
118-
119-
if (call_consume_changes_idle_id == 0)
120-
{
121-
call_consume_changes_idle_id =
122-
g_idle_add (call_consume_changes_idle_cb, NULL);
123-
}
142+
schedule_call_consume_changes ();
124143
}
125144

126145
CajaMonitor *
@@ -129,16 +148,33 @@ caja_monitor_directory (GFile *location)
129148
GFileMonitor *dir_monitor;
130149
CajaMonitor *ret;
131150

151+
ret = g_new0 (CajaMonitor, 1);
132152
dir_monitor = g_file_monitor_directory (location, G_FILE_MONITOR_WATCH_MOUNTS, NULL, NULL);
133153

134-
ret = g_new0 (CajaMonitor, 1);
135-
ret->monitor = dir_monitor;
154+
if (dir_monitor != NULL) {
155+
ret->monitor = dir_monitor;
156+
}
136157

137-
if (ret->monitor)
138-
{
158+
else if (!g_file_is_native (location)) {
159+
ret->mount = caja_get_mounted_mount_for_root (location);
160+
ret->location = g_object_ref (location);
161+
ret->volume_monitor = g_volume_monitor_get ();
162+
}
163+
164+
if (ret->monitor != NULL) {
165+
g_signal_connect (ret->monitor, "changed",
166+
G_CALLBACK (dir_changed), ret);
167+
}
168+
169+
if (ret->monitor) {
139170
g_signal_connect (ret->monitor, "changed", (GCallback)dir_changed, ret);
140171
}
141172

173+
if (ret->volume_monitor != NULL) {
174+
g_signal_connect (ret->volume_monitor, "mount-removed",
175+
G_CALLBACK (mount_removed), ret);
176+
}
177+
142178
/* We return a monitor even on failure, so we can avoid later trying again */
143179
return ret;
144180
}
@@ -153,5 +189,12 @@ caja_monitor_cancel (CajaMonitor *monitor)
153189
g_object_unref (monitor->monitor);
154190
}
155191

192+
if (monitor->volume_monitor != NULL) {
193+
g_signal_handlers_disconnect_by_func (monitor->volume_monitor, mount_removed, monitor);
194+
g_object_unref (monitor->volume_monitor);
195+
}
196+
197+
g_clear_object (&monitor->location);
198+
g_clear_object (&monitor->mount);
156199
g_free (monitor);
157200
}

0 commit comments

Comments
 (0)