[gtk/wip/chergert/quartz4u: 138/142] macos: grab when starting drag



commit 5a8f5d6b487604da325a59bd800cc8a9c65e6d11
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jun 18 17:20:26 2020 -0700

    macos: grab when starting drag

 gdk/macos/gdkmacosdrag-private.h |  5 +++-
 gdk/macos/gdkmacosdrag.c         | 51 +++++++++++++++++++++++++++++++++++++++-
 gdk/macos/gdkmacossurface.c      |  7 +++++-
 3 files changed, 60 insertions(+), 3 deletions(-)
---
diff --git a/gdk/macos/gdkmacosdrag-private.h b/gdk/macos/gdkmacosdrag-private.h
index 7abd2b2270..98075f27ef 100644
--- a/gdk/macos/gdkmacosdrag-private.h
+++ b/gdk/macos/gdkmacosdrag-private.h
@@ -41,6 +41,8 @@ struct _GdkMacosDrag
   GdkDrag parent_instance;
 
   GdkMacosDragSurface *drag_surface;
+  GdkSeat *drag_seat;
+  GdkCursor *cursor;
 
   int hot_x;
   int hot_y;
@@ -60,7 +62,8 @@ struct _GdkMacosDragClass
   GdkDragClass parent_class;
 };
 
-GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
+GType    gdk_macos_drag_get_type (void) G_GNUC_CONST;
+gboolean _gdk_macos_drag_begin   (GdkMacosDrag *self);
 
 G_END_DECLS
 
diff --git a/gdk/macos/gdkmacosdrag.c b/gdk/macos/gdkmacosdrag.c
index 6d077540a5..70982a709a 100644
--- a/gdk/macos/gdkmacosdrag.c
+++ b/gdk/macos/gdkmacosdrag.c
@@ -165,17 +165,52 @@ static void
 gdk_macos_drag_set_cursor (GdkDrag   *drag,
                            GdkCursor *cursor)
 {
+  GdkMacosDrag *self = (GdkMacosDrag *)drag;
   NSCursor *nscursor;
 
-  g_assert (GDK_IS_MACOS_DRAG (drag));
+  g_assert (GDK_IS_MACOS_DRAG (self));
   g_assert (!cursor || GDK_IS_CURSOR (cursor));
 
+  g_set_object (&self->cursor, cursor);
+
   nscursor = _gdk_macos_cursor_get_ns_cursor (cursor);
 
   if (nscursor != NULL)
     [nscursor set];
 }
 
+static gboolean
+drag_grab (GdkMacosDrag *self)
+{
+  GdkSeat *seat;
+
+  g_assert (GDK_IS_MACOS_DRAG (self));
+
+  seat = gdk_device_get_seat (gdk_drag_get_device (GDK_DRAG (self)));
+
+  if (gdk_seat_grab (seat,
+                     GDK_SURFACE (self->drag_surface),
+                     GDK_SEAT_CAPABILITY_ALL_POINTING,
+                     FALSE,
+                     self->cursor,
+                     NULL,
+                     NULL,
+                     NULL) != GDK_GRAB_SUCCESS)
+    return FALSE;
+
+  g_set_object (&self->drag_seat, seat);
+
+  return TRUE;
+}
+
+static void
+drag_ungrab (GdkMacosDrag *self)
+{
+  g_assert (GDK_IS_MACOS_DRAG (self));
+
+  gdk_seat_ungrab (self->drag_seat);
+}
+
 static void
 gdk_macos_drag_cancel (GdkDrag             *drag,
                        GdkDragCancelReason  reason)
@@ -184,6 +219,7 @@ gdk_macos_drag_cancel (GdkDrag             *drag,
 
   g_assert (GDK_IS_MACOS_DRAG (self));
 
+  drag_ungrab (self);
   gdk_drag_drop_done (drag, FALSE);
 
   self->cancelled = TRUE;
@@ -480,6 +516,9 @@ gdk_macos_drag_finalize (GObject *object)
   GdkMacosDrag *self = (GdkMacosDrag *)object;
   GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
 
+  g_clear_object (&self->cursor);
+  g_clear_object (&self->drag_seat);
+
   G_OBJECT_CLASS (gdk_macos_drag_parent_class)->finalize (object);
 
   if (drag_surface)
@@ -556,3 +595,13 @@ static void
 gdk_macos_drag_init (GdkMacosDrag *self)
 {
 }
+
+gboolean
+_gdk_macos_drag_begin (GdkMacosDrag *self)
+{
+  g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
+
+  _gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
+
+  return drag_grab (self);
+}
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 9d22ae9a53..ee99b6bdba 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -323,10 +323,15 @@ gdk_macos_surface_drag_begin (GdkSurface         *surface,
   cursor = gdk_drag_get_cursor (GDK_DRAG (drag),
                                 gdk_drag_get_selected_action (GDK_DRAG (drag)));
   gdk_drag_set_cursor (GDK_DRAG (drag), cursor);
-  gdk_seat_ungrab (seat);
 
   g_clear_object (&drag_surface);
 
+  if (!_gdk_macos_drag_begin (drag))
+    {
+      g_object_unref (drag);
+      return NULL;
+    }
+
   /* Hold a reference until drop_done is called */
   g_object_ref (drag);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]