diff options
author | Carlos Soriano <csoriano@gnome.org> | 2016-04-04 23:44:59 +0200 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2016-04-05 15:13:09 +0200 |
commit | 87ff4118a205f31c2d964b1a7f6109378697fa18 (patch) | |
tree | ffaf72f24681fbe810379bda731af3d83530b77c | |
parent | e3ddb9720fafe5637dfb94db2b1774f586e4e158 (diff) | |
download | nautilus-87ff4118a205f31c2d964b1a7f6109378697fa18.tar.gz |
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.
-rw-r--r-- | libnautilus-private/nautilus-canvas-dnd.c | 26 | ||||
-rw-r--r-- | libnautilus-private/nautilus-desktop-directory-file.c | 3 | ||||
-rw-r--r-- | libnautilus-private/nautilus-dnd.c | 31 | ||||
-rw-r--r-- | libnautilus-private/nautilus-dnd.h | 8 |
4 files changed, 62 insertions, 6 deletions
diff --git a/libnautilus-private/nautilus-canvas-dnd.c b/libnautilus-private/nautilus-canvas-dnd.c index f4b63e6c8..2c1adb24b 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, + done, 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 e990de218..2a43bdf98 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 d2f7ee358..5c651392c 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') { @@ -355,7 +376,7 @@ check_same_fs (NautilusFile *file1, if (id1 != NULL && id2 != NULL) { result = (strcmp (id1, id2) == 0); - } + } g_free (id1); g_free (id2); @@ -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 52b4e368c..b73d02e01 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 |