[nautilus] nautilus-dnd: request file system info if not available



commit 149d38386790831e39419fafa84eb8d476d1e64c
Author: Carlos Soriano <csoriano gnome org>
Date:   Wed Apr 6 10:37:56 2016 +0200

    nautilus-dnd: request file system info if not available
    
    We were assuming we had in cache the files used for dnd, but with
    the desktop split that's not longer the case.
    
    What can happens is that we cannot discern whether the drop action
    should be a copy or a move, since Nautilus always performs a move if
    the file system is the same as the dragged files.
    
    To fix it, in a best effort mode, we will request to update the files
    information if it's not available. In future times it will be requested,
    and if the files are not freed, we will have the file system information
    available in order to decide a more appropriate drop action.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=712620

 libnautilus-private/nautilus-canvas-dnd.c          |   26 +++++++++++++++++
 .../nautilus-desktop-directory-file.c              |    3 +-
 libnautilus-private/nautilus-dnd.c                 |   29 +++++++++++++++++---
 libnautilus-private/nautilus-dnd.h                 |    8 +++++
 4 files changed, 61 insertions(+), 5 deletions(-)
---
diff --git a/libnautilus-private/nautilus-canvas-dnd.c b/libnautilus-private/nautilus-canvas-dnd.c
index f4b63e6..60ed964 100644
--- a/libnautilus-private/nautilus-canvas-dnd.c
+++ b/libnautilus-private/nautilus-canvas-dnd.c
@@ -358,6 +358,28 @@ nautilus_canvas_container_position_shadow (NautilusCanvasContainer *container,
 }
 
 static void
+stop_cache_selection_list (NautilusDragInfo *drag_info)
+{
+        if (drag_info->file_list_info_handler) {
+                nautilus_file_list_cancel_call_when_ready (drag_info->file_list_info_handler);
+        }
+}
+
+static void
+cache_selection_list (NautilusDragInfo *drag_info)
+{
+        GList *files;
+
+        files = nautilus_drag_file_list_from_selection_list (drag_info->selection_list);
+        nautilus_file_list_call_when_ready (files,
+                                            NAUTILUS_FILE_ATTRIBUTE_INFO,
+                                            drag_info->file_list_info_handler,
+                                            NULL, NULL);
+
+        g_list_free_full (files, g_object_unref);
+}
+
+static void
 nautilus_canvas_container_dropped_canvas_feedback (GtkWidget *widget,
                                               GtkSelectionData *data,
                                               int x, int y)
@@ -369,6 +391,7 @@ nautilus_canvas_container_dropped_canvas_feedback (GtkWidget *widget,
        dnd_info = container->details->dnd_info;
        
        /* Delete old selection list. */
+        stop_cache_selection_list (&dnd_info->drag_info);
        nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list);
        dnd_info->drag_info.selection_list = NULL;
 
@@ -381,6 +404,7 @@ nautilus_canvas_container_dropped_canvas_feedback (GtkWidget *widget,
 
        /* Build the selection list and the shadow. */
        dnd_info->drag_info.selection_list = nautilus_drag_build_selection_list (data);
+        cache_selection_list (&dnd_info->drag_info);
        dnd_info->shadow = create_selection_shadow (container, dnd_info->drag_info.selection_list);
        nautilus_canvas_container_position_shadow (container, x, y);
 }
@@ -535,6 +559,7 @@ drag_end_callback (GtkWidget *widget,
         window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container)));
        dnd_info = container->details->dnd_info;
 
+        stop_cache_selection_list (&dnd_info->drag_info);
        nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list);
        nautilus_drag_destroy_selection_list (container->details->dnd_source_info->selection_cache);
        dnd_info->drag_info.selection_list = NULL;
@@ -1077,6 +1102,7 @@ nautilus_canvas_container_receive_dropped_icons (NautilusCanvasContainer *contai
        }
 
        g_free (drop_target);
+        stop_cache_selection_list (&container->details->dnd_info->drag_info);
        nautilus_drag_destroy_selection_list (container->details->dnd_info->drag_info.selection_list);
        container->details->dnd_info->drag_info.selection_list = NULL;
 }
diff --git a/libnautilus-private/nautilus-desktop-directory-file.c 
b/libnautilus-private/nautilus-desktop-directory-file.c
index e990de2..2a43bdf 100644
--- a/libnautilus-private/nautilus-desktop-directory-file.c
+++ b/libnautilus-private/nautilus-desktop-directory-file.c
@@ -107,7 +107,8 @@ get_delegated_attributes_mask (void)
 {
        return NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS |
                NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
-               NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES;
+               NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES |
+                NAUTILUS_FILE_ATTRIBUTE_INFO;
 }
 
 static void
diff --git a/libnautilus-private/nautilus-dnd.c b/libnautilus-private/nautilus-dnd.c
index d2f7ee3..db3e905 100644
--- a/libnautilus-private/nautilus-dnd.c
+++ b/libnautilus-private/nautilus-dnd.c
@@ -135,6 +135,27 @@ nautilus_drag_uri_list_from_selection_list (const GList *selection_list)
        return g_list_reverse (uri_list);
 }
 
+/*
+ * Transfer: Full. Free with g_list_free_full (list, g_object_unref);
+ */
+GList *
+nautilus_drag_file_list_from_selection_list (const GList *selection_list)
+{
+       NautilusDragSelectionItem *selection_item;
+       GList *file_list;
+       const GList *l;
+
+       file_list = NULL;
+       for (l = selection_list; l != NULL; l = l->next) {
+               selection_item = (NautilusDragSelectionItem *) l->data;
+               if (selection_item->file != NULL) {
+                       file_list = g_list_prepend (file_list, g_object_ref (selection_item->file));
+               }
+       }
+
+       return g_list_reverse (file_list);
+}
+
 GList *
 nautilus_drag_uri_list_from_array (const char **uris)
 {
@@ -189,7 +210,7 @@ nautilus_drag_build_selection_list (GtkSelectionData *data)
                item->uri = g_malloc (len + 1);
                memcpy (item->uri, oldp, len);
                item->uri[len] = 0;
-               item->file = nautilus_file_get_existing_by_uri (item->uri);
+               item->file = nautilus_file_get_by_uri (item->uri);
 
                p++;
                if (*p == '\n' || *p == '\0') {
@@ -371,7 +392,7 @@ source_is_deletable (GFile *file)
        gboolean ret;
 
        /* if there's no a cached NautilusFile, it returns NULL */
-       naut_file = nautilus_file_get_existing (file);
+       naut_file = nautilus_file_get (file);
        if (naut_file == NULL) {
                return FALSE;
        }
@@ -466,7 +487,7 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
        
        dropped_uri = ((NautilusDragSelectionItem *)items->data)->uri;
        dropped_file = ((NautilusDragSelectionItem *)items->data)->file;
-       target_file = nautilus_file_get_existing_by_uri (target_uri_string);
+       target_file = nautilus_file_get_by_uri (target_uri_string);
 
        if (eel_uri_is_desktop (dropped_uri) &&
            !eel_uri_is_desktop (target_uri_string)) {
@@ -607,7 +628,7 @@ cache_one_item (const char *uri,
 
        item = nautilus_drag_selection_item_new ();
        item->uri = g_strdup (uri);
-       item->file = nautilus_file_get_existing_by_uri (uri);
+       item->file = nautilus_file_get_by_uri (uri);
        item->icon_x = x;
        item->icon_y = y;
        item->icon_width = w;
diff --git a/libnautilus-private/nautilus-dnd.h b/libnautilus-private/nautilus-dnd.h
index 52b4e36..b73d02e 100644
--- a/libnautilus-private/nautilus-dnd.h
+++ b/libnautilus-private/nautilus-dnd.h
@@ -78,6 +78,12 @@ typedef struct {
        /* cache of selected URIs, representing items being dragged */
        GList *selection_cache;
 
+        /* File selection list information request handler, for the call for
+         * information (mostly the file system info, in order to know if we want
+         * co copy or move the files) about the files being dragged, that can
+         * come from another nautilus process, like the desktop. */
+        NautilusFileListHandle *file_list_info_handler;
+
        /* has the drop occured ? */
        gboolean drop_occured;
 
@@ -156,4 +162,6 @@ gboolean                nautilus_drag_selection_includes_special_link (GList              
                *sele
 
 NautilusDragInfo *          nautilus_drag_get_source_data                 (GdkDragContext                    
 *context);
 
+GList *                     nautilus_drag_file_list_from_selection_list   (const GList                       
 *selection_list);
+
 #endif


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