diff options
| author | Mattias Andrée <m@maandree.se> | 2026-10-13 23:00:56 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-10-13 23:00:56 +0200 |
| commit | 0476071164c36b41de5b19e3e8a768feb422f27f (patch) | |
| tree | 09d16e177042b14020a48030176d99e9024bea66 /dropping.c | |
| parent | Third commit (diff) | |
| download | gbild-0476071164c36b41de5b19e3e8a768feb422f27f.tar.gz gbild-0476071164c36b41de5b19e3e8a768feb422f27f.tar.bz2 gbild-0476071164c36b41de5b19e3e8a768feb422f27f.tar.xz | |
Fourth commit
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
| -rw-r--r-- | dropping.c | 65 |
1 files changed, 64 insertions, 1 deletions
@@ -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; @@ -85,6 +102,31 @@ out: } 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) { GdkWindow *event_window = gtk_widget_get_window(widget); @@ -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); } |
