1 Index: gtk/gtktreeview.c
2 ===================================================================
3 --- gtk/gtktreeview.c (revision 21770)
4 +++ gtk/gtktreeview.c (working copy)
6 gboolean row_double_click = FALSE;
8 gboolean node_selected;
9 + gboolean edits_allowed;
12 if (tree_view->priv->tree == NULL)
13 @@ -2643,9 +2644,17 @@
15 tree_view->priv->focus_column = column;
19 + if (g_object_get_data (G_OBJECT(tree_view), "mouse-edits-require-mod1")) {
20 + edits_allowed = (event->state & GDK_MOD1_MASK);
22 + /* regular GTK design: do edits if none of the default modifiers are active */
23 + edits_allowed = !(event->state & gtk_accelerator_get_default_mod_mask ());
26 /* decide if we edit */
27 - if (event->type == GDK_BUTTON_PRESS && event->button == 1 &&
28 - !(event->state & gtk_accelerator_get_default_mod_mask ()))
29 + if (event->type == GDK_BUTTON_PRESS && event->button == 1 && edits_allowed)
33 Index: gtk/gtkquartz.c
34 ===================================================================
35 --- gtk/gtkquartz.c (revision 21770)
36 +++ gtk/gtkquartz.c (working copy)
41 +_gtk_quartz_create_image_from_drawable (GdkDrawable* drawable)
44 + NSImage* image = NULL;
46 + pixbuf = gdk_pixbuf_get_from_drawable (NULL, drawable, NULL,
51 + image = _gtk_quartz_create_image_from_pixbuf (pixbuf);
58 _gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf)
60 CGColorSpaceRef colorspace;
61 Index: gtk/gtkquartz.h
62 ===================================================================
63 --- gtk/gtkquartz.h (revision 21770)
64 +++ gtk/gtkquartz.h (working copy)
66 GtkSelectionData *selection_data);
68 NSImage *_gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf);
69 +NSImage *_gtk_quartz_create_image_from_drawable (GdkDrawable *drawable);
73 Index: gtk/gtktooltip.c
74 ===================================================================
75 --- gtk/gtktooltip.c (revision 21770)
76 +++ gtk/gtktooltip.c (working copy)
78 gtk_tooltip_trigger_tooltip_query (GdkDisplay *display)
89 + gdk_window_get_origin (window, &rx, &ry);
91 event.type = GDK_MOTION_NOTIFY;
92 event.motion.window = window;
94 + event.motion.x_root = rx + x;
96 + event.motion.y_root = ry + y;
97 event.motion.is_hint = FALSE;
99 _gtk_tooltip_handle_event (&event);
100 Index: gtk/gtkdnd-quartz.c
101 ===================================================================
102 --- gtk/gtkdnd-quartz.c (revision 21770)
103 +++ gtk/gtkdnd-quartz.c (working copy)
106 static void gtk_drag_source_site_destroy (gpointer data);
108 +static GtkDragSourceInfo *gtk_drag_get_source_info (GdkDragContext *context,
111 +extern GdkDragContext *gdk_quartz_drag_source_context(); /* gdk/quartz/gdkdnd-quartz.c */
113 struct _GtkDragSourceSite
115 GdkModifierType start_button_mask;
118 struct _GtkDragSourceInfo
120 + GtkWidget *source_widget;
122 GtkTargetList *target_list; /* Targets for drag data */
123 GdkDragAction possible_actions; /* Actions allowed by source */
124 GdkDragContext *context; /* drag context */
126 + NSEvent *nsevent; /* what started it */
127 gint hot_x, hot_y; /* Hot spot for drag */
128 GdkPixbuf *icon_pixbuf;
133 struct _GtkDragDestSite
141 if (site && site->flags & GTK_DEST_DEFAULT_DROP)
143 gtk_drag_finish (context,
144 @@ -233,19 +243,24 @@
150 -gtk_drag_get_source_widget (GdkDragContext *context)
156 gtk_drag_finish (GdkDragContext *context,
161 + GtkDragSourceInfo *info;
162 + GdkDragContext* source_context = gdk_quartz_drag_source_context ();
164 + if (source_context)
166 + info = gtk_drag_get_source_info (source_context, FALSE);
169 + info->success = success;
170 + info->delete = del;
177 g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
181 +gtk_drag_get_source_widget (GdkDragContext *context)
183 + GtkDragSourceInfo *info;
184 + GdkDragContext* real_source_context = gdk_quartz_drag_source_context();
186 + if (!real_source_context)
189 + info = gtk_drag_get_source_info (real_source_context, FALSE);
193 + return info->source_widget;
196 /*************************************************************
197 * gtk_drag_highlight_expose:
198 * Callback for expose_event for highlighted widgets.
200 gtk_drag_get_data (widget, context, target, time);
203 + /* leave a note for the source-side context about the action chosen */
205 g_signal_emit_by_name (widget, "drag-drop",
206 context, x, y, time, &retval);
208 @@ -1031,6 +1064,45 @@
213 +gtk_drag_begin_idle (gpointer arg)
215 + GdkDragContext* context = (GdkDragContext*) arg;
216 + GtkDragSourceInfo* info = gtk_drag_get_source_info (context, FALSE);
217 + NSWindow *nswindow;
218 + NSPasteboard *pasteboard;
219 + GtkDragSourceOwner *owner;
222 + g_assert (info != NULL);
224 + pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
225 + owner = [[GtkDragSourceOwner alloc] initWithInfo:info];
227 + [pasteboard declareTypes:_gtk_quartz_target_list_to_pasteboard_types (info->target_list) owner:owner];
229 + if ((nswindow = get_toplevel_nswindow (info->source_widget)) == NULL)
232 + /* Ref the context. It's unreffed when the drag has been aborted */
233 + g_object_ref (info->context);
235 + /* FIXME: If the event isn't a mouse event, use the global cursor position instead */
236 + point = [info->nsevent locationInWindow];
238 + [nswindow dragImage:_gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf)
240 + offset:NSMakeSize(0, 0)
241 + event:info->nsevent
242 + pasteboard:pasteboard
246 + [info->nsevent release];
251 static GdkDragContext *
252 gtk_drag_begin_internal (GtkWidget *widget,
253 GtkDragSourceSite *site,
254 @@ -1042,16 +1114,13 @@
255 GtkDragSourceInfo *info;
256 GdkDragContext *context;
258 - NSPasteboard *pasteboard;
259 - GtkDragSourceOwner *owner;
263 context = gdk_drag_begin (NULL, NULL);
264 context->is_source = TRUE;
266 info = gtk_drag_get_source_info (context, TRUE);
268 + info->source_widget = g_object_ref (widget);
269 info->widget = g_object_ref (widget);
270 info->target_list = target_list;
271 gtk_target_list_ref (target_list);
272 @@ -1086,13 +1155,13 @@
275 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 1, 1);
276 - gdk_pixbuf_fill (pixbuf, 0xffffff);
278 - gtk_drag_set_icon_pixbuf (context,
280 + gdk_pixbuf_fill (pixbuf, 0xffffff);
282 + gtk_drag_set_icon_pixbuf (context,
286 - g_object_unref (pixbuf);
287 + g_object_unref (pixbuf);
290 case GTK_IMAGE_PIXBUF:
291 @@ -1117,31 +1186,17 @@
295 - gdk_pointer_ungrab (0);
297 - pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
298 - owner = [[GtkDragSourceOwner alloc] initWithInfo:info];
299 + nswindow = get_toplevel_nswindow (widget);
300 + info->nsevent = [nswindow currentEvent];
301 + [info->nsevent retain];
303 - [pasteboard declareTypes:_gtk_quartz_target_list_to_pasteboard_types (target_list) owner:owner];
304 + /* drag will begin in an idle handler to avoid nested run loops */
306 - /* Ref the context. It's unreffed when the drag has been aborted */
307 - g_object_ref (info->context);
308 + g_idle_add_full (G_PRIORITY_HIGH_IDLE, gtk_drag_begin_idle, context, NULL);
310 - nswindow = get_toplevel_nswindow (widget);
311 + gdk_pointer_ungrab (0);
313 - /* FIXME: If the event isn't a mouse event, use the global cursor position instead */
314 - nsevent = [nswindow currentEvent];
315 - point = [nsevent locationInWindow];
317 - [nswindow dragImage:_gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf)
319 - offset:NSMakeSize(0, 0)
321 - pasteboard:pasteboard
325 - return info->context;
330 @@ -1668,7 +1723,20 @@
334 - g_warning ("gtk_drag_set_icon_pixmap is not supported on Mac OS X");
337 + g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
338 + g_return_if_fail (context->is_source);
339 + g_return_if_fail (GDK_IS_COLORMAP (colormap));
340 + g_return_if_fail (GDK_IS_PIXMAP (pixmap));
342 + pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, colormap,
347 + gtk_drag_set_icon_pixbuf (context, pixbuf, hot_x, hot_y);
348 + g_object_unref (pixbuf);
352 @@ -1760,6 +1828,9 @@
353 g_signal_emit_by_name (info->widget, "drag-end",
356 + if (info->source_widget)
357 + g_object_unref (info->source_widget);
360 g_object_unref (info->widget);
362 @@ -1781,6 +1852,10 @@
364 gtk_drag_drop_finished (GtkDragSourceInfo *info)
366 + if (info->success && info->delete)
367 + g_signal_emit_by_name (info->source_widget, "drag-data-delete",
370 /* Workaround for the fact that the NS API blocks until the drag is
371 * over. This way the context is still valid when returning from
372 * drag_begin, even if it will still be quite useless. See bug #501588.
373 Index: gdk/quartz/gdkevents-quartz.c
374 ===================================================================
375 --- gdk/quartz/gdkevents-quartz.c (revision 21770)
376 +++ gdk/quartz/gdkevents-quartz.c (working copy)
378 return ((GdkEventPrivate *) event)->windowing_data;
381 +/* A category that exposes the protected carbon event for an NSEvent. */
382 +@interface NSEvent (GdkQuartzNSEvent)
383 +- (void *)gdk_quartz_event_ref;
386 +@implementation NSEvent (GdkQuartzNSEvent)
387 +- (void *)gdk_quartz_event_ref
394 _gdk_events_init (void)
396 @@ -1668,6 +1680,65 @@
400 +_gdk_quartz_possibly_forward_accelerator (NSEvent* nsevent)
402 + /* Special-case menu shortcut events. We create command events for
403 + * those and forward to the corresponding menu.
405 + if ((!_gdk_quartz_keyboard_grab_window ||
406 + (_gdk_quartz_keyboard_grab_window && keyboard_grab_owner_events)) &&
407 + [nsevent type] == NSKeyDown)
409 + EventRef event_ref;
411 + MenuItemIndex index;
413 + event_ref = [nsevent gdk_quartz_event_ref];
414 + if (IsMenuKeyEvent (NULL, event_ref,
415 + kMenuEventQueryOnly,
416 + &menu_ref, &index))
418 + MenuCommand menu_command;
419 + HICommand hi_command;
421 + if (GetMenuItemCommandID (menu_ref, index, &menu_command) != noErr)
424 + hi_command.commandID = menu_command;
425 + hi_command.menu.menuRef = menu_ref;
426 + hi_command.menu.menuItemIndex = index;
428 + CreateEvent (NULL, kEventClassCommand, kEventCommandProcess,
429 + 0, kEventAttributeUserEvent, &event_ref);
430 + SetEventParameter (event_ref, kEventParamDirectObject,
432 + sizeof (HICommand), &hi_command);
434 + SendEventToEventTarget (event_ref, GetMenuEventTarget (menu_ref));
436 + ReleaseEvent (event_ref);
445 +gdk_quartz_possibly_forward (GdkEvent* event)
448 + g_return_val_if_fail (event != NULL, FALSE);
450 + nsevent = ((GdkEventPrivate*)event)->windowing_data;
453 + return _gdk_quartz_possibly_forward_accelerator (nsevent);
459 gdk_event_translate (NSEvent *nsevent)
462 Index: gdk/quartz/gdkdnd-quartz.c
463 ===================================================================
464 --- gdk/quartz/gdkdnd-quartz.c (revision 21770)
465 +++ gdk/quartz/gdkdnd-quartz.c (working copy)
468 GdkDragContext *_gdk_quartz_drag_source_context = NULL;
471 +gdk_quartz_drag_source_context()
473 + return _gdk_quartz_drag_source_context;
477 gdk_drag_begin (GdkWindow *window,
479 Index: gdk/quartz/GdkQuartzWindow.c
480 ===================================================================
481 --- gdk/quartz/GdkQuartzWindow.c (revision 21770)
482 +++ gdk/quartz/GdkQuartzWindow.c (working copy)
485 GdkDragAction result = 0;
487 + /* GDK and Quartz drag operations do not map 1:1.
488 + This mapping represents about the best that we
491 + Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE
492 + have almost opposite meanings: the GDK one means that the
493 + destination is solely responsible for the action; the Quartz
494 + one means that the source and destination will agree
495 + privately on the action. NSOperationGeneric is close in meaning
496 + to GDK_ACTION_PRIVATE but there is a problem: it will be
497 + sent for any ordinary drag, and likely not understood
498 + by any intra-widget drag (since the source & dest are the
502 if (operation & NSDragOperationGeneric)
503 + result |= GDK_ACTION_MOVE;
504 + if (operation & NSDragOperationCopy)
505 result |= GDK_ACTION_COPY;
506 + if (operation & NSDragOperationMove)
507 + result |= GDK_ACTION_MOVE;
508 + if (operation & NSDragOperationLink)
509 + result |= GDK_ACTION_LINK;
515 if (action & GDK_ACTION_COPY)
516 result |= NSDragOperationCopy;
517 + if (action & GDK_ACTION_LINK)
518 + result |= NSDragOperationLink;
519 + if (action & GDK_ACTION_MOVE)
520 + result |= NSDragOperationMove;
526 GDK_DRAG_CONTEXT_PRIVATE (current_context)->dragging_info = sender;
527 current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
528 + current_context->actions = current_context->suggested_action;
531 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
534 - (void)draggingEnded:(id <NSDraggingInfo>)sender
536 + /* leave a note for the source about what action was taken */
537 + if (_gdk_quartz_drag_source_context && current_context)
538 + _gdk_quartz_drag_source_context->action = current_context->action;
541 g_object_unref (current_context);
542 current_context = NULL;