aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2023-06-05 14:53:06 +0200
committerPřemysl Eric Janouch <p@janouch.name>2023-06-05 15:42:38 +0200
commita3745df84bc272ad0240797750b9b6cfe1b39827 (patch)
tree1748f959c5baca6c2f1bd18891a1ef41f6e42aeb
parentcc59e537dab61d6dc1799498b891f6e4ee1b96bf (diff)
downloadfiv-a3745df84bc272ad0240797750b9b6cfe1b39827.tar.gz
fiv-a3745df84bc272ad0240797750b9b6cfe1b39827.tar.xz
fiv-a3745df84bc272ad0240797750b9b6cfe1b39827.zip
Fix monitoring of file renames
-rw-r--r--fiv-io-model.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/fiv-io-model.c b/fiv-io-model.c
index 58cf632..423e4fb 100644
--- a/fiv-io-model.c
+++ b/fiv-io-model.c
@@ -330,6 +330,36 @@ model_find(const GPtrArray *target, GFile *file, FivIoModelEntry **entry)
return -1;
}
+enum monitor_event {
+ MONITOR_NONE,
+ MONITOR_CHANGING,
+ MONITOR_RENAMING,
+ MONITOR_REMOVING,
+ MONITOR_ADDING
+};
+
+static void
+monitor_apply(enum monitor_event event, GPtrArray *target, int index,
+ FivIoModelEntry *new_entry)
+{
+ // The file used to be filtered out but isn't anymore.
+ // TODO(p): Handle the inverse transition as well.
+ if (event == MONITOR_RENAMING && index < 0)
+ event = MONITOR_ADDING;
+
+ if (event == MONITOR_CHANGING) {
+ g_assert(new_entry != NULL);
+ fiv_io_model_entry_unref(target->pdata[index]);
+ target->pdata[index] = fiv_io_model_entry_ref(new_entry);
+ }
+ if (event == MONITOR_REMOVING || event == MONITOR_RENAMING)
+ g_ptr_array_remove_index(target, index);
+ if (event == MONITOR_RENAMING || event == MONITOR_ADDING) {
+ g_assert(new_entry != NULL);
+ g_ptr_array_add(target, fiv_io_model_entry_ref(new_entry));
+ }
+}
+
static void
on_monitor_changed(G_GNUC_UNUSED GFileMonitor *monitor, GFile *file,
GFile *other_file, GFileMonitorEvent event_type, gpointer user_data)
@@ -340,25 +370,25 @@ on_monitor_changed(G_GNUC_UNUSED GFileMonitor *monitor, GFile *file,
gint files_index = model_find(self->files, file, &old_entry);
gint subdirs_index = model_find(self->subdirs, file, &old_entry);
- enum { NONE, CHANGING, RENAMING, REMOVING, ADDING } action = NONE;
+ enum monitor_event action = MONITOR_NONE;
GFile *new_entry_file = NULL;
switch (event_type) {
case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
- action = CHANGING;
+ action = MONITOR_CHANGING;
new_entry_file = file;
break;
case G_FILE_MONITOR_EVENT_RENAMED:
- action = RENAMING;
+ action = MONITOR_RENAMING;
new_entry_file = other_file;
break;
case G_FILE_MONITOR_EVENT_DELETED:
case G_FILE_MONITOR_EVENT_MOVED_OUT:
- action = REMOVING;
+ action = MONITOR_REMOVING;
break;
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_MOVED_IN:
- action = ADDING;
+ action = MONITOR_ADDING;
old_entry = NULL;
new_entry_file = file;
break;
@@ -402,36 +432,12 @@ run:
fiv_io_model_entry_ref(old_entry);
if (files_index != -1 || new_target == self->files) {
- if (action == CHANGING) {
- g_assert(new_entry != NULL);
- fiv_io_model_entry_unref(self->files->pdata[files_index]);
- self->files->pdata[files_index] =
- fiv_io_model_entry_ref(new_entry);
- }
- if (action == REMOVING || action == RENAMING)
- g_ptr_array_remove_index(self->files, files_index);
- if (action == RENAMING || action == ADDING) {
- g_assert(new_entry != NULL);
- g_ptr_array_add(self->files, fiv_io_model_entry_ref(new_entry));
- }
-
+ monitor_apply(action, self->files, files_index, new_entry);
g_signal_emit(self, model_signals[FILES_CHANGED],
0, old_entry, new_entry);
}
if (subdirs_index != -1 || new_target == self->subdirs) {
- if (action == CHANGING) {
- g_assert(new_entry != NULL);
- fiv_io_model_entry_unref(self->subdirs->pdata[subdirs_index]);
- self->subdirs->pdata[subdirs_index] =
- fiv_io_model_entry_ref(new_entry);
- }
- if (action == REMOVING || action == RENAMING)
- g_ptr_array_remove_index(self->subdirs, subdirs_index);
- if (action == RENAMING || action == ADDING) {
- g_assert(new_entry != NULL);
- g_ptr_array_add(self->subdirs, fiv_io_model_entry_ref(new_entry));
- }
-
+ monitor_apply(action, self->subdirs, subdirs_index, new_entry);
g_signal_emit(self, model_signals[SUBDIRECTORIES_CHANGED],
0, old_entry, new_entry);
}