macos: Queue events during drag
authorArjan Molenaar <gaphor@gmail.com>
Mon, 16 Jan 2023 13:47:49 +0000 (14:47 +0100)
committerArjan Molenaar <gaphor@gmail.com>
Mon, 16 Jan 2023 13:47:49 +0000 (14:47 +0100)
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
gdk/macos/gdkmacoseventsource-private.h
gdk/macos/gdkmacoseventsource.c

index 79e2ec8001bad323d525dcef4ce332fd264da1ea..1005d0c83774060615d764cae31bfe247d6706e1 100644 (file)
@@ -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
index 09853a18ac3ae08ceaf33ec7898200d655cf8f25..66579546d240ffe9e68d9d1a33f95941b9a941d1 100644 (file)
@@ -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
 
index 725cc57476087b416e7540edb3489c1f6c8a23da..5725e2850f93cccddf19f11f61f172d475e569f6 100644 (file)
@@ -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;
 }