[gtk/wip/chergert/gdk-macos-gdkdrag] wip on drag sources



commit ee9000212c0407c2379e4e9a42f0618824e2a441
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jun 18 22:29:56 2021 -0700

    wip on drag sources

 gdk/macos/GdkMacosBaseView.c     | 20 ++++++++
 gdk/macos/gdkmacosdrag-private.h |  9 +++-
 gdk/macos/gdkmacosdrag.c         | 99 ++++++++++++++++++++++++++++++++--------
 gdk/macos/gdkmacossurface.c      | 10 +++-
 4 files changed, 117 insertions(+), 21 deletions(-)
---
diff --git a/gdk/macos/GdkMacosBaseView.c b/gdk/macos/GdkMacosBaseView.c
index c4ba8c1020..bd86e0f414 100644
--- a/gdk/macos/GdkMacosBaseView.c
+++ b/gdk/macos/GdkMacosBaseView.c
@@ -696,4 +696,24 @@
                      GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
 }
 
+- (void)draggingSession:(NSDraggingSession *)session
+           endedAtPoint:(NSPoint)screenPoint
+              operation:(NSDragOperation)operation
+{
+  NSInteger sequence = [session draggingSequenceNumber];
+  GdkMacosDisplay *display = [self gdkDisplay];
+  GdkDrag *drag = _gdk_macos_display_find_drag (display, sequence);
+  gboolean success = operation != NSDragOperationNone;
+
+  if (drag == NULL)
+    return;
+
+  g_print ("Dragging session ended!: success=%d\n", success);
+
+  if (!success)
+    gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
+  else
+    g_signal_emit_by_name (drag, "dnd-finished");
+}
+
 @end
diff --git a/gdk/macos/gdkmacosdrag-private.h b/gdk/macos/gdkmacosdrag-private.h
index 98075f27ef..dc5f732f5a 100644
--- a/gdk/macos/gdkmacosdrag-private.h
+++ b/gdk/macos/gdkmacosdrag-private.h
@@ -23,6 +23,7 @@
 #include "gdkdragprivate.h"
 
 #include "gdkmacosdragsurface-private.h"
+#include "gdkmacospasteboard-private.h"
 
 G_BEGIN_DECLS
 
@@ -44,6 +45,8 @@ struct _GdkMacosDrag
   GdkSeat *drag_seat;
   GdkCursor *cursor;
 
+  NSInteger sequence;
+
   int hot_x;
   int hot_y;
 
@@ -63,7 +66,11 @@ struct _GdkMacosDragClass
 };
 
 GType    gdk_macos_drag_get_type (void) G_GNUC_CONST;
-gboolean _gdk_macos_drag_begin   (GdkMacosDrag *self);
+gboolean _gdk_macos_drag_begin   (GdkMacosDrag       *self,
+                                  GdkContentProvider *provider,
+                                  NSWindow           *window,
+                                  double              quartz_x,
+                                  double              quartz_y);
 
 G_END_DECLS
 
diff --git a/gdk/macos/gdkmacosdrag.c b/gdk/macos/gdkmacosdrag.c
index ee4b5e7020..cf1b514c88 100644
--- a/gdk/macos/gdkmacosdrag.c
+++ b/gdk/macos/gdkmacosdrag.c
@@ -49,6 +49,17 @@ enum {
 
 static GParamSpec *properties [N_PROPS];
 
+static void
+gdk_macos_drag_drop_from_display (GdkMacosDrag *self)
+{
+  GdkDisplay *display;
+
+  g_assert (GDK_IS_MACOS_DRAG (self));
+
+  display = gdk_drag_get_display (GDK_DRAG (self));
+  _gdk_macos_display_set_drag (GDK_MACOS_DISPLAY (display), self->sequence, NULL);
+}
+
 static double
 ease_out_cubic (double t)
 {
@@ -81,12 +92,12 @@ gdk_macos_zoomback_timeout (gpointer data)
   frame_clock = zb->frame_clock;
 
   if (!frame_clock)
-    return G_SOURCE_REMOVE;
+    goto hide_surface;
 
   current_time = gdk_frame_clock_get_frame_time (frame_clock);
   f = (current_time - zb->start_time) / (double) ANIM_TIME;
   if (f >= 1.0)
-    return G_SOURCE_REMOVE;
+    goto hide_surface;
 
   t = ease_out_cubic (f);
 
@@ -101,6 +112,11 @@ gdk_macos_zoomback_timeout (gpointer data)
   _gdk_macos_surface_show (GDK_MACOS_SURFACE (drag->drag_surface));
 
   return G_SOURCE_CONTINUE;
+
+hide_surface:
+  gdk_surface_hide (GDK_SURFACE (drag->drag_surface));
+
+  return G_SOURCE_REMOVE;
 }
 
 static GdkSurface *
@@ -142,6 +158,8 @@ gdk_macos_drag_drop_done (GdkDrag  *drag,
 
   g_assert (GDK_IS_MACOS_DRAG (self));
 
+  g_print ("Drop done! success=%d\n", success);
+
   if (success)
     {
       gdk_surface_hide (GDK_SURFACE (self->drag_surface));
@@ -231,20 +249,8 @@ gdk_macos_drag_cancel (GdkDrag             *drag,
 
   self->cancelled = TRUE;
   drag_ungrab (self);
-  gdk_drag_drop_done (drag, FALSE);
-}
-
-static void
-gdk_macos_drag_drop_performed (GdkDrag *drag,
-                               guint32  time)
-{
-  GdkMacosDrag *self = (GdkMacosDrag *)drag;
-
-  g_assert (GDK_IS_MACOS_DRAG (self));
-
-  drag_ungrab (self);
-  g_signal_emit_by_name (drag, "dnd-finished");
-  gdk_drag_drop_done (drag, TRUE);
+  gdk_surface_hide (GDK_SURFACE (self->drag_surface));
+  gdk_macos_drag_drop_from_display (self);
 }
 
 static void
@@ -503,6 +509,9 @@ gdk_macos_drag_handle_event (GdkDrag  *drag,
   g_assert (GDK_IS_MACOS_DRAG (drag));
   g_assert (event != NULL);
 
+  if (GDK_MACOS_DRAG (drag)->cancelled)
+    return FALSE;
+
   switch ((guint) event->event_type)
     {
     case GDK_MOTION_NOTIFY:
@@ -523,6 +532,12 @@ gdk_macos_drag_handle_event (GdkDrag  *drag,
     }
 }
 
+static void
+gdk_macos_drag_dnd_finished (GdkDrag *drag)
+{
+  gdk_macos_drag_drop_from_display (GDK_MACOS_DRAG (drag));
+}
+
 static void
 gdk_macos_drag_finalize (GObject *object)
 {
@@ -591,8 +606,8 @@ gdk_macos_drag_class_init (GdkMacosDragClass *klass)
   drag_class->drop_done = gdk_macos_drag_drop_done;
   drag_class->set_cursor = gdk_macos_drag_set_cursor;
   drag_class->cancel = gdk_macos_drag_cancel;
-  drag_class->drop_performed = gdk_macos_drag_drop_performed;
   drag_class->handle_event = gdk_macos_drag_handle_event;
+  drag_class->dnd_finished = gdk_macos_drag_dnd_finished;
 
   properties [PROP_DRAG_SURFACE] =
     g_param_spec_object ("drag-surface",
@@ -610,11 +625,57 @@ gdk_macos_drag_init (GdkMacosDrag *self)
 }
 
 gboolean
-_gdk_macos_drag_begin (GdkMacosDrag *self)
+_gdk_macos_drag_begin (GdkMacosDrag       *self,
+                       GdkContentProvider *content,
+                       NSWindow           *window,
+                       double              quartz_x,
+                       double              quartz_y)
 {
+  NSArray<NSDraggingItem *> *items;
+  NSDraggingSession *session;
+  NSPasteboardItem *item;
+  NSTimeInterval nstime;
+  NSEvent *nsevent;
+
   g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
 
+  GDK_BEGIN_MACOS_ALLOC_POOL;
+
+  item = [[GdkMacosPasteboardItem alloc] initForDrag:GDK_DRAG (self) withContentProvider:content];
+  items = [NSArray arrayWithObject:item];
+
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  nstime = [[NSDate dateWithTimeIntervalSince1970: (gint64)time / 1000L] timeIntervalSinceReferenceDate];
+  nsevent = [NSEvent mouseEventWithType: NSEventTypeLeftMouseDown
+                               location: NSMakePoint (quartz_x, quartz_y)
+                          modifierFlags: 0
+                              timestamp: nstime
+                           windowNumber: [window windowNumber]
+                                context: [window graphicsContext]
+                            eventNumber: 0
+                             clickCount: 1
+                               pressure: 0.0];
+  G_GNUC_END_IGNORE_DEPRECATIONS
+
+  session = [[window contentView] beginDraggingSessionWithItems:items
+                                                          event:nsevent
+                                                         source:[window contentView]];
+  self->sequence = [session draggingSequenceNumber];
+
+  GDK_END_MACOS_ALLOC_POOL;
+
+  gdk_surface_hide (GDK_SURFACE (self->drag_surface));
+#if 0
   _gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
 
-  return drag_grab (self);
+  if (drag_grab (self))
+#endif
+    {
+      _gdk_macos_display_set_drag (GDK_MACOS_DISPLAY (gdk_drag_get_display (GDK_DRAG (self))),
+                                   self->sequence,
+                                   GDK_DRAG (self));
+      return TRUE;
+    }
+
+  //return FALSE;
 }
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 9a1f73835b..7af3d3117d 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -313,10 +313,12 @@ gdk_macos_surface_drag_begin (GdkSurface         *surface,
   GdkMacosSurface *self = (GdkMacosSurface *)surface;
   GdkMacosSurface *drag_surface;
   GdkMacosDrag *drag;
+  GdkDisplay *display;
   GdkCursor *cursor;
   GdkSeat *seat;
   double px;
   double py;
+  int quartz_x, quartz_y;
   int sx;
   int sy;
 
@@ -326,6 +328,12 @@ gdk_macos_surface_drag_begin (GdkSurface         *surface,
   g_assert (GDK_IS_MACOS_DEVICE (device));
   g_assert (GDK_IS_CONTENT_PROVIDER (content));
 
+  display = gdk_surface_get_display (surface);
+  _gdk_macos_display_to_display_coords (GDK_MACOS_DISPLAY (display),
+                                        surface->x + dx,
+                                        surface->y + dy,
+                                        &quartz_x, &quartz_y);
+
   seat = gdk_device_get_seat (device);
   gdk_macos_device_query_state (device, surface, NULL, &px, &py, NULL);
   _gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
@@ -346,7 +354,7 @@ gdk_macos_surface_drag_begin (GdkSurface         *surface,
                                 gdk_drag_get_selected_action (GDK_DRAG (drag)));
   gdk_drag_set_cursor (GDK_DRAG (drag), cursor);
 
-  if (!_gdk_macos_drag_begin (drag))
+  if (!_gdk_macos_drag_begin (drag, content, self->window, quartz_x, quartz_y))
     {
       g_object_unref (drag);
       return NULL;


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