From 1bc63eeadb911f0f6ba9358f1443e613b98bbbc5 Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Mon, 16 Jan 2023 14:47:49 +0100 Subject: [PATCH] macos: Queue events during drag By passing the events during a (midal-ish) drag operation to the main loop, we're able to keep up with what's happening. This allows the internal drag state (GtkDragSource) to be updated and be done when the drag is done. --- gdk/macos/GdkMacosWindow.c | 5 ++++ gdk/macos/gdkmacoseventsource-private.h | 1 + gdk/macos/gdkmacoseventsource.c | 35 +++++++++++++------------ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c index 79e2ec8001..1005d0c837 100644 --- a/gdk/macos/GdkMacosWindow.c +++ b/gdk/macos/GdkMacosWindow.c @@ -30,6 +30,7 @@ #include "gdkmacosdisplay-private.h" #include "gdkmacosdrag-private.h" #include "gdkmacosdrop-private.h" +#include "gdkmacoseventsource-private.h" #include "gdkmacosmonitor-private.h" #include "gdkmacospasteboard-private.h" #include "gdkmacossurface-private.h" @@ -701,6 +702,8 @@ typedef NSString *CALayerContentsGravity; GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number); int x, y; + _gdk_macos_event_source_queue_event ([NSApp currentEvent]); + _gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display), screenPoint.x, screenPoint.y, &x, &y); _gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y); } @@ -711,6 +714,8 @@ typedef NSString *CALayerContentsGravity; GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface)); GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number); + _gdk_macos_event_source_queue_event ([NSApp currentEvent]); + if (gdk_drag_get_selected_action (drag) != 0) g_signal_emit_by_name (drag, "drop-performed"); else diff --git a/gdk/macos/gdkmacoseventsource-private.h b/gdk/macos/gdkmacoseventsource-private.h index 09853a18ac..66579546d2 100644 --- a/gdk/macos/gdkmacoseventsource-private.h +++ b/gdk/macos/gdkmacoseventsource-private.h @@ -34,6 +34,7 @@ typedef enum GSource *_gdk_macos_event_source_new (GdkMacosDisplay *display); NSEvent *_gdk_macos_event_source_get_pending (void); gboolean _gdk_macos_event_source_check_pending (void); +void _gdk_macos_event_source_queue_event (NSEvent *event); G_END_DECLS diff --git a/gdk/macos/gdkmacoseventsource.c b/gdk/macos/gdkmacoseventsource.c index 725cc57476..5725e2850f 100644 --- a/gdk/macos/gdkmacoseventsource.c +++ b/gdk/macos/gdkmacoseventsource.c @@ -640,6 +640,23 @@ _gdk_macos_event_source_get_pending (void) return event; } +void +_gdk_macos_event_source_queue_event (NSEvent *event) +{ + /* Just used to wake us up; if an event and a FD arrived at the same + * time; could have come from a previous iteration in some cases, + * but the spurious wake up is harmless if a little inefficient. + */ + if (!event || + ([event type] == NSEventTypeApplicationDefined && + [event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP)) + return; + + if (!current_events) + current_events = g_queue_new (); + g_queue_push_head (current_events, [event retain]); +} + static gboolean gdk_macos_event_source_prepare (GSource *source, int *timeout) @@ -782,23 +799,7 @@ poll_func (GPollFD *ufds, if (last_ufds == ufds && n_ready < 0) n_ready = select_thread_collect_poll (ufds, nfds); - if (event && - [event type] == NSEventTypeApplicationDefined && - [event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP) - { - /* Just used to wake us up; if an event and a FD arrived at the same - * time; could have come from a previous iteration in some cases, - * but the spurious wake up is harmless if a little inefficient. - */ - event = NULL; - } - - if (event) - { - if (!current_events) - current_events = g_queue_new (); - g_queue_push_head (current_events, [event retain]); - } + _gdk_macos_event_source_queue_event (event); return n_ready; }