[nautilus/BUG_usb] nautilus-directory: handle change events




commit 9b97d4f99339e78f1d94b756550b0397d3a5f21e
Author: Nelson Benítez León <nbenitezl+gnome gmail com>
Date:   Tue Sep 12 22:35:45 2017 +0500

    nautilus-directory: handle change events
    
    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

 src/nautilus-directory-async.c   | 20 ++++++++++++++++++++
 src/nautilus-directory-private.h |  6 ++++++
 src/nautilus-directory.c         | 15 +++++++++++++++
 3 files changed, 41 insertions(+)
---
diff --git a/src/nautilus-directory-async.c b/src/nautilus-directory-async.c
index 901f5a38f..5fa29ae91 100644
--- a/src/nautilus-directory-async.c
+++ b/src/nautilus-directory-async.c
@@ -931,6 +931,22 @@ should_skip_file (NautilusDirectory *directory,
     return FALSE;
 }
 
+static void
+notify_files_changed_while_being_added (NautilusDirectory *directory)
+{
+    if (directory->details->files_changed_while_adding == NULL)
+    {
+        return;
+    }
+
+    directory->details->files_changed_while_adding =
+        g_list_reverse (directory->details->files_changed_while_adding);
+
+    nautilus_directory_notify_files_changed (directory->details->files_changed_while_adding);
+
+    g_clear_list (&directory->details->files_changed_while_adding, g_object_unref);
+}
+
 static gboolean
 dequeue_pending_idle_callback (gpointer callback_data)
 {
@@ -1084,6 +1100,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. */
+    notify_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..0f8fb1b2e 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 *files_changed_while_adding;
+
        DirectoryCountState *count_in_progress;
 
        NautilusFile *deep_count_file;
diff --git a/src/nautilus-directory.c b/src/nautilus-directory.c
index ff0c0d9b2..1a9947ff9 100644
--- a/src/nautilus-directory.c
+++ b/src/nautilus-directory.c
@@ -217,6 +217,7 @@ nautilus_directory_finalize (GObject *object)
     nautilus_file_queue_destroy (directory->details->high_priority_queue);
     nautilus_file_queue_destroy (directory->details->low_priority_queue);
     nautilus_file_queue_destroy (directory->details->extension_queue);
+    g_clear_list (&directory->details->files_changed_while_adding, g_object_unref);
     g_assert (directory->details->directory_load_in_progress == NULL);
     g_assert (directory->details->count_in_progress == NULL);
     g_assert (directory->details->dequeue_pending_idle_id == 0);
@@ -1319,6 +1320,8 @@ nautilus_directory_notify_files_changed (GList *files)
     GHashTable *changed_lists;
     GList *node;
     GFile *location;
+    g_autoptr (GFile) parent = NULL;
+    g_autoptr (NautilusDirectory) dir = NULL;
     NautilusFile *file;
 
     /* Make a list of changed files in each directory. */
@@ -1345,6 +1348,18 @@ 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->files_changed_while_adding)
+            {
+                dir->details->files_changed_while_adding =
+                    g_list_prepend (dir->details->files_changed_while_adding,
+                                    g_object_ref (location));
+            }
+        }
     }
 
     /* Now send out the changed signals. */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]