summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Berla <corey@berla.me>2023-04-12 14:57:25 -0700
committerCorey Berla <corey@berla.me>2023-04-12 15:21:58 -0700
commit1a3dbdf12d351fbcd48c6c6037db2134c38250eb (patch)
tree0beb5820de7b5a2001a6048a3528d7fc2d83c94e
parent252a0395fcfbbd82891f050733d6a93c4da9a25e (diff)
downloadnautilus-wip/corey/dnd-texture.tar.gz
general: Allow DnD a texture to nautiluswip/corey/dnd-texture
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
-rw-r--r--src/nautilus-dnd.c7
-rw-r--r--src/nautilus-files-view.c10
-rw-r--r--src/nautilus-files-view.h3
-rw-r--r--src/nautilus-list-base.c6
-rw-r--r--src/nautilus-pathbar.c6
-rw-r--r--src/nautilus-window.c4
6 files changed, 30 insertions, 6 deletions
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);