summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNelson Benítez León <nbenitezl+gnome@gmail.com>2017-09-12 22:35:45 +0500
committerAntónio Fernandes <antoniojpfernandes@gmail.com>2021-05-22 10:49:54 +0000
commit9078a0ecb462907e5de101d6bf4458a437617ec6 (patch)
treead7ab3930e8715b239fa85bed8ffc357270793a0
parentc10cd96379860d243e6b17775a36c86c455c2cb7 (diff)
downloadnautilus-BUG_usb.tar.gz
nautilus-directory: handle change eventsBUG_usb
for files that were still not known to nautilus because they were in the midst of being added to Nautilus. This happens when eg. inotify fires two consecutive NEW + CHANGE events for a new file, and it's important to handle the CHANGE event as the file may have changed its properties with respect the ones reported at the time the NEW event fired. A case this happens is for mountpoint directories of removable devices, as seen in the referenced bug below. We now queue CHANGE events received for files unknown to Nautilus only when the parent folder is currently adding new files. When the folder finish adding the new files, we then process the list of queued files. If there are still files unknown to Nautilus in this list, they will be ignored as before. https://bugzilla.gnome.org/show_bug.cgi?id=703179 Issue #1576
-rw-r--r--src/nautilus-directory-async.c24
-rw-r--r--src/nautilus-directory-private.h6
-rw-r--r--src/nautilus-directory.c23
3 files changed, 53 insertions, 0 deletions
diff --git a/src/nautilus-directory-async.c b/src/nautilus-directory-async.c
index d5b93b5ac..813f2fb25 100644
--- a/src/nautilus-directory-async.c
+++ b/src/nautilus-directory-async.c
@@ -578,6 +578,9 @@ new_files_cancel (NautilusDirectory *directory)
g_list_free (directory->details->new_files_in_progress);
directory->details->new_files_in_progress = NULL;
}
+
+ g_clear_list (&directory->details->new_files_in_progress_changes,
+ (GDestroyNotify) g_object_unref);
}
static int
@@ -931,6 +934,23 @@ should_skip_file (NautilusDirectory *directory,
return FALSE;
}
+static void
+process_files_changed_while_being_added (NautilusDirectory *directory)
+{
+ if (directory->details->new_files_in_progress_changes == NULL)
+ {
+ return;
+ }
+
+ directory->details->new_files_in_progress_changes =
+ g_list_reverse (directory->details->new_files_in_progress_changes);
+
+ nautilus_directory_notify_files_changed (directory->details->new_files_in_progress_changes);
+
+ g_clear_list (&directory->details->new_files_in_progress_changes,
+ (GDestroyNotify) g_object_unref);
+}
+
static gboolean
dequeue_pending_idle_callback (gpointer callback_data)
{
@@ -1084,6 +1104,10 @@ dequeue_pending_idle_callback (gpointer callback_data)
directory->details->directory_loaded_sent_notification = TRUE;
}
+ /* Process changes received for files while they were still being added.
+ * See Bug 703179 and issue #1576 for a situation this happens. */
+ process_files_changed_while_being_added (directory);
+
drain:
g_list_free_full (pending_file_info, g_object_unref);
diff --git a/src/nautilus-directory-private.h b/src/nautilus-directory-private.h
index 8f1a23590..d0b3f3dad 100644
--- a/src/nautilus-directory-private.h
+++ b/src/nautilus-directory-private.h
@@ -100,6 +100,12 @@ struct NautilusDirectoryDetails
GList *new_files_in_progress; /* list of NewFilesState * */
+ /* List of GFile's that received CHANGE events while new files were being added in
+ * that same folder. We will process this CHANGE events after new_files_in_progress
+ * list is finished. See Bug 703179 and issue #1576 for a case when this happens.
+ */
+ GList *new_files_in_progress_changes;
+
DirectoryCountState *count_in_progress;
NautilusFile *deep_count_file;
diff --git a/src/nautilus-directory.c b/src/nautilus-directory.c
index 527b6bf93..a0e3dd34f 100644
--- a/src/nautilus-directory.c
+++ b/src/nautilus-directory.c
@@ -1319,6 +1319,8 @@ nautilus_directory_notify_files_changed (GList *files)
GHashTable *changed_lists;
GList *node;
GFile *location;
+ GFile *parent;
+ NautilusDirectory *dir;
NautilusFile *file;
/* Make a list of changed files in each directory. */
@@ -1345,6 +1347,27 @@ nautilus_directory_notify_files_changed (GList *files)
hash_table_list_prepend (changed_lists, directory, file);
}
+ else
+ {
+ parent = g_file_get_parent (location);
+ dir = nautilus_directory_get_existing (parent);
+ if (dir != NULL && dir->details->new_files_in_progress != NULL &&
+ files != dir->details->new_files_in_progress_changes)
+ {
+ dir->details->new_files_in_progress_changes =
+ g_list_prepend (dir->details->new_files_in_progress_changes,
+ g_object_ref (location));
+ }
+
+ if (dir != NULL)
+ {
+ nautilus_directory_unref (dir);
+ }
+ if (parent != NULL)
+ {
+ g_object_unref (parent);
+ }
+ }
}
/* Now send out the changed signals. */