From 1a3dbdf12d351fbcd48c6c6037db2134c38250eb Mon Sep 17 00:00:00 2001 From: Corey Berla Date: Wed, 12 Apr 2023 14:57:25 -0700 Subject: general: Allow DnD a texture to nautilus We generally accept drops for types GDK_TYPE_FILE_LIST and G_TYPE_STRING. Sometimes, an image (commonly from a web browser) will offer a GDK_TYPE_FILE_LIST and a GDK_TYPE_TEXT. Simply using a file list to save an image has several potential disadvantages including: 1) Inconsistent / unexpected file names 2) Inconsistent behavior (i.e. a link to the image, rather than the image itself may be saved) 3) Portal issues Although, not clearly documented, the gtk_drop_target_set_gtypes, creates a priority order for the type to be presented in ::drop. Put GDK_TYPE_TEXTURE before GDK_TYPE_FILE_LIST since, typically if both are available, we prefer a texture. Fixes: https://gitlab.gnome.org/GNOME/nautilus/-/issues/2889 --- src/nautilus-dnd.c | 7 +++++++ src/nautilus-files-view.c | 10 ++++++++++ src/nautilus-files-view.h | 3 +++ src/nautilus-list-base.c | 6 +++--- src/nautilus-pathbar.c | 6 +++++- src/nautilus-window.c | 4 ++-- 6 files changed, 30 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nautilus-dnd.c b/src/nautilus-dnd.c index 5e6cfead0..8d1ef0f4d 100644 --- a/src/nautilus-dnd.c +++ b/src/nautilus-dnd.c @@ -11,6 +11,7 @@ #include "nautilus-directory.h" #include "nautilus-dnd.h" #include "nautilus-file-utilities.h" +#include "nautilus-files-view.h" #include "nautilus-files-view-dnd.h" #include "nautilus-tag-manager.h" @@ -256,6 +257,12 @@ nautilus_dnd_perform_drop (NautilusFilesView *view, target_uri, action); return TRUE; } + else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE)) + { + g_autofree char *dest_uri = g_file_get_uri (target_location); + + nautilus_file_view_save_image (view, value, dest_uri); + } else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST)) { GSList *source_file_list = g_value_get_boxed (value); diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c index abc9a39b7..3e263f75f 100644 --- a/src/nautilus-files-view.c +++ b/src/nautilus-files-view.c @@ -9046,6 +9046,16 @@ nautilus_files_view_get_uri (NautilusFilesView *view) return nautilus_directory_get_uri (priv->model); } +void nautilus_file_view_save_image (NautilusFilesView *view, + const GValue *value, + const char *dest_uri) +{ + nautilus_file_operations_save_image_from_texture (GTK_WIDGET (view), NULL, + dest_uri, + g_value_get_object (value), + copy_move_done_callback, pre_copy_move (view)); +} + void nautilus_files_view_move_copy_items (NautilusFilesView *view, const GList *item_uris, diff --git a/src/nautilus-files-view.h b/src/nautilus-files-view.h index 536c613f6..3d8d5c07f 100644 --- a/src/nautilus-files-view.h +++ b/src/nautilus-files-view.h @@ -274,6 +274,9 @@ void nautilus_files_view_move_copy_items (NautilusFilesV const GList *item_uris, const char *target_uri, int copy_action); +void nautilus_file_view_save_image (NautilusFilesView *view, + const GValue *value, + const char *target_uri); void nautilus_files_view_new_file_with_initial_contents (NautilusFilesView *view, const char *parent_uri, const char *filename, diff --git a/src/nautilus-list-base.c b/src/nautilus-list-base.c index 8d16c682e..82f6f9ae3 100644 --- a/src/nautilus-list-base.c +++ b/src/nautilus-list-base.c @@ -678,7 +678,7 @@ get_preferred_action (NautilusFile *target_file, action = nautilus_dnd_get_preferred_action (target_file, NULL); } } - else if (G_VALUE_HOLDS (value, G_TYPE_STRING)) + else if (G_VALUE_HOLDS (value, G_TYPE_STRING) || G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE)) { action = GDK_ACTION_COPY; } @@ -944,7 +944,7 @@ setup_cell_common (GtkListItem *listitem, drop_target = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_ALL); gtk_drop_target_set_preload (drop_target, TRUE); /* TODO: Implement GDK_TYPE_STRING */ - gtk_drop_target_set_gtypes (drop_target, (GType[2]) { GDK_TYPE_FILE_LIST, G_TYPE_STRING }, 2); + gtk_drop_target_set_gtypes (drop_target, (GType[3]) { GDK_TYPE_TEXTURE, GDK_TYPE_FILE_LIST, G_TYPE_STRING }, 3); g_signal_connect (drop_target, "enter", G_CALLBACK (on_item_drag_enter), cell); g_signal_connect (drop_target, "notify::value", G_CALLBACK (on_item_drag_value_notify), cell); g_signal_connect (drop_target, "leave", G_CALLBACK (on_item_drag_leave), cell); @@ -1892,7 +1892,7 @@ nautilus_list_base_setup_gestures (NautilusListBase *self) drop_target = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_ALL); gtk_drop_target_set_preload (drop_target, TRUE); /* TODO: Implement GDK_TYPE_STRING */ - gtk_drop_target_set_gtypes (drop_target, (GType[2]) { GDK_TYPE_FILE_LIST, G_TYPE_STRING }, 2); + gtk_drop_target_set_gtypes (drop_target, (GType[3]) { GDK_TYPE_TEXTURE, GDK_TYPE_FILE_LIST, G_TYPE_STRING }, 3); g_signal_connect (drop_target, "enter", G_CALLBACK (on_view_drag_enter), self); g_signal_connect (drop_target, "notify::value", G_CALLBACK (on_view_drag_value_notify), self); g_signal_connect (drop_target, "motion", G_CALLBACK (on_view_drag_motion), self); diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c index 83d8994c0..76676df32 100644 --- a/src/nautilus-pathbar.c +++ b/src/nautilus-pathbar.c @@ -771,6 +771,10 @@ on_drag_motion (GtkDropTarget *target, action = nautilus_dnd_get_preferred_action (button_data->file, items->data); } } + else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE)) + { + action = GDK_ACTION_COPY; + } start = button_data->hover_start_point; if (gtk_drag_check_threshold (button_data->button, start.x, start.y, x, y)) @@ -1288,7 +1292,7 @@ make_button_data (NautilusPathBar *self, gtk_drop_target_set_preload (target, TRUE); /* TODO: Implement GDK_TYPE_STRING */ - gtk_drop_target_set_gtypes (target, (GType[1]) { GDK_TYPE_FILE_LIST }, 1); + gtk_drop_target_set_gtypes (target, (GType[2]) { GDK_TYPE_TEXTURE, GDK_TYPE_FILE_LIST }, 2); g_signal_connect (target, "enter", G_CALLBACK (on_drag_motion), button_data); g_signal_connect (target, "motion", G_CALLBACK (on_drag_motion), button_data); g_signal_connect (target, "drop", G_CALLBACK (on_drag_drop), button_data); diff --git a/src/nautilus-window.c b/src/nautilus-window.c index 9424f154d..3ba24d661 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -1488,7 +1488,7 @@ extra_drag_value_cb (AdwTabBar *self, action = nautilus_dnd_get_preferred_action (file, G_FILE (file_list->data)); } } - else if (G_VALUE_HOLDS (value, G_TYPE_STRING)) + else if (G_VALUE_HOLDS (value, G_TYPE_STRING) || G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE)) { action = GDK_ACTION_COPY; } @@ -1636,7 +1636,7 @@ nautilus_window_constructed (GObject *self) */ adw_tab_bar_setup_extra_drop_target (window->tab_bar, GDK_ACTION_COPY | GDK_ACTION_MOVE, - (GType [2]) {GDK_TYPE_FILE_LIST, G_TYPE_STRING}, 2); + (GType [3]) {GDK_TYPE_TEXTURE, GDK_TYPE_FILE_LIST, G_TYPE_STRING}, 3); adw_tab_bar_set_extra_drag_preload (window->tab_bar, TRUE); g_signal_connect (window->tab_bar, "extra-drag-value", G_CALLBACK (extra_drag_value_cb), NULL); g_signal_connect (window->tab_bar, "extra-drag-drop", G_CALLBACK (extra_drag_drop_cb), NULL); -- cgit v1.2.1