From 0476071164c36b41de5b19e3e8a768feb422f27f Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Tue, 13 Oct 2026 23:00:56 +0200 Subject: Fourth commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- dropping.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'dropping.c') diff --git a/dropping.c b/dropping.c index 412f0ab..e7bf20f 100644 --- a/dropping.c +++ b/dropping.c @@ -4,7 +4,12 @@ static char url_list_name[] = "text/uri-list"; static GtkTargetEntry url_list = {url_list_name, 0u, 0u}; -static size_t +static unsigned int active_drop_timer; +static GdkDragContext *active_drop_context; +static GtkWidget *active_drop_widget; +static GdkDragAction active_drop_action; + +size_t get_dropped_files(struct file **files_out, char **uris) { GError *error = NULL; @@ -55,6 +60,18 @@ drop_files(GtkWidget *widget, GdkDragContext *context, int x, int y, (void) info; (void) user; + if (active_drop_timer) { + g_source_remove(active_drop_timer); + active_drop_timer = 0; + } + + if (gtk_drag_get_source_widget(context) == collection_view) { + if (widget == display_area) + navigate_collection_drag(); + else + accepted = 0; + goto out; + } if (gtk_drag_get_source_widget(context) == display_area) { accepted = 0; goto out; @@ -84,6 +101,31 @@ out: g_strfreev(uris); } +static int +poll_modifiers(void *user) +{ + GdkModifierType modifiers; + GdkDragAction action = 0; + + (void) user; + + if (!GTK_WIDGET_REALIZED(active_drop_widget)) + return 1; + + gdk_window_get_pointer(active_drop_widget->window, NULL, NULL, &modifiers); + + action = (modifiers & GDK_CONTROL_MASK) ? GDK_ACTION_COPY : GDK_ACTION_MOVE; + if (!(gdk_drag_context_get_actions(active_drop_context) & action)) + action = 0; + + if (action != active_drop_action) { + active_drop_action = action; + gdk_drag_status(active_drop_context, action, GDK_CURRENT_TIME); + } + + return 1; +} + static int drop_motion(GtkWidget *widget, GdkDragContext *context, int x, int y, unsigned int time, void *user) { @@ -107,14 +149,35 @@ drop_motion(GtkWidget *widget, GdkDragContext *context, int x, int y, unsigned i out: gdk_drag_status(context, action, time); + + if (!active_drop_timer) { + active_drop_context = context; + active_drop_widget = widget; + active_drop_action = action; + active_drop_timer = g_timeout_add(50, &poll_modifiers, NULL); + } return 1; } +static void +drop_leave(GtkWidget *widget, GdkDragContext *context, unsigned int time, void *user) +{ + (void) widget; + (void) context; + (void) time; + (void) user; + if (active_drop_timer) { + g_source_remove(active_drop_timer); + active_drop_timer = 0; + } +} + void set_up_dropping(void) { gtk_drag_dest_set(window, GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, &url_list, 1u, GDK_ACTION_COPY | GDK_ACTION_MOVE); g_signal_connect(window, "drag-motion", G_CALLBACK(&drop_motion), NULL); + g_signal_connect(window, "drag-leave", G_CALLBACK(&drop_leave), NULL); g_signal_connect(window, "drag-data-received", G_CALLBACK(&drop_files), NULL); } -- cgit v1.3.1