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 *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;