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




commit a5e0a6c633179fef1c9f2cd0b40d4e8c6edf0b22
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   | 24 ++++++++++++++++++++++++
 src/nautilus-directory-private.h |  6 ++++++
 src/nautilus-directory.c         | 23 +++++++++++++++++++++++
 3 files changed, 53 insertions(+)
---
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. */


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