diff options
author | John Ralls <jralls@ceridwen.us> | 2011-09-24 18:19:56 -0700 |
---|---|---|
committer | John Ralls <jralls@ceridwen.us> | 2011-10-09 11:24:41 -0700 |
commit | 6906ab88bc9f5b9694953948c8d61f6f40718a9e (patch) | |
tree | be3c43bdd5a69bd0d88cb1a9b4021bc737cbf491 /gtk/gtkdnd-quartz.c | |
parent | 8ad3d2b29656b3af312b752c62ff68e7059fc326 (diff) | |
download | gtk+-6906ab88bc9f5b9694953948c8d61f6f40718a9e.tar.gz |
Bug 658767 - Drag and Drop NSEvent capture is racy
Create a synthetic NSMouseLeftDown to store in the GtkQuartzDragSourceInfo
rather than relying on the NSWindow's latest event being the right one (or the
right kind).
Diffstat (limited to 'gtk/gtkdnd-quartz.c')
-rw-r--r-- | gtk/gtkdnd-quartz.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/gtk/gtkdnd-quartz.c b/gtk/gtkdnd-quartz.c index 6d4e709a94..0653261c65 100644 --- a/gtk/gtkdnd-quartz.c +++ b/gtk/gtkdnd-quartz.c @@ -1100,6 +1100,13 @@ gtk_drag_begin_idle (gpointer arg) return FALSE; } +/* Fake protocol to let us call GdkNSView gdkWindow without including + * gdk/GdkNSView.h (which we can't because it pulls in the internal-only + * gdkwindow.h). + */ +@protocol GdkNSView +- (GdkWindow *)gdkWindow; +@end static GdkDragContext * gtk_drag_begin_internal (GtkWidget *widget, @@ -1110,14 +1117,47 @@ gtk_drag_begin_internal (GtkWidget *widget, GdkEvent *event) { GtkDragSourceInfo *info; - GdkDragContext *context; GdkDevice *pointer; - NSWindow *nswindow; - - context = gdk_drag_begin (gtk_widget_get_window (widget), NULL); + GdkWindow *window; + GdkDragContext *context = gdk_drag_begin (gtk_widget_get_window (widget), + NULL); + NSWindow *nswindow = get_toplevel_nswindow (widget); + NSPoint point = {0, 0}; + gdouble x, y; + double time = (double)g_get_real_time (); + NSEvent *nsevent; + NSTimeInterval nstime; + + if (event) + { + if (gdk_event_get_coords (event, &x, &y)) + { + point.x = x; + point.y = y; + } + time = (double)gdk_event_get_time (event); + } + nstime = [[NSDate dateWithTimeIntervalSince1970: time / 1000] timeIntervalSinceReferenceDate]; + nsevent = [NSEvent mouseEventWithType: NSLeftMouseDown + location: point + modifierFlags: 0 + timestamp: nstime + windowNumber: [nswindow windowNumber] + context: [nswindow graphicsContext] + eventNumber: 0 + clickCount: 1 + pressure: 0.0 ]; + + window = [(id<GdkNSView>)[nswindow contentView] gdkWindow]; + g_return_val_if_fail(nsevent != NULL, NULL); + + context = gdk_drag_begin (window, NULL); + g_return_val_if_fail( context != NULL, NULL); info = gtk_drag_get_source_info (context, TRUE); - + info->nsevent = nsevent; + [info->nsevent retain]; + info->source_widget = g_object_ref (widget); info->widget = g_object_ref (widget); info->target_list = target_list; @@ -1160,10 +1200,6 @@ gtk_drag_begin_internal (GtkWidget *widget, } } - nswindow = get_toplevel_nswindow (widget); - info->nsevent = [nswindow currentEvent]; - [info->nsevent retain]; - /* drag will begin in an idle handler to avoid nested run loops */ g_idle_add_full (G_PRIORITY_HIGH_IDLE, gtk_drag_begin_idle, context, NULL); @@ -1802,7 +1838,7 @@ gtk_drag_source_info_destroy (GtkDragSourceInfo *info) pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard]; [pasteboard declareTypes: nil owner: nil]; - [pool relase]; + [pool release]; gtk_drag_clear_source_info (info->context); g_object_unref (info->context); |