Fix ExportFormatSpecification copy-c'tor
[ardour.git] / patches / gtk-osx.patch
1 Index: gtk/gtktreeview.c
2 ===================================================================
3 --- gtk/gtktreeview.c   (revision 21770)
4 +++ gtk/gtktreeview.c   (working copy)
5 @@ -2534,6 +2534,7 @@
6        gboolean row_double_click = FALSE;
7        gboolean rtl;
8        gboolean node_selected;
9 +      gboolean edits_allowed;
10  
11        /* Empty tree? */
12        if (tree_view->priv->tree == NULL)
13 @@ -2643,9 +2644,17 @@
14  
15        tree_view->priv->focus_column = column;
16  
17 +      /* ARDOUR HACK */
18 +
19 +      if (g_object_get_data (G_OBJECT(tree_view), "mouse-edits-require-mod1")) {
20 +             edits_allowed = (event->state & GDK_MOD1_MASK);
21 +      } else {
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 ());
24 +      }
25 +
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)
30         {
31           GtkTreePath *anchor;
32           GtkTreeIter iter;
33 Index: gtk/gtkquartz.c
34 ===================================================================
35 --- gtk/gtkquartz.c     (revision 21770)
36 +++ gtk/gtkquartz.c     (working copy)
37 @@ -24,6 +24,23 @@
38  #include "gtkalias.h"
39  
40  NSImage *
41 +_gtk_quartz_create_image_from_drawable (GdkDrawable* drawable)
42 +{
43 +       GdkPixbuf* pixbuf;
44 +       NSImage* image = NULL;
45 +
46 +       pixbuf = gdk_pixbuf_get_from_drawable (NULL, drawable, NULL, 
47 +                                                 0, 0, /* src */
48 +                                                 0, 0, /* dst */
49 +                                                 -1, -1);
50 +       if (pixbuf) 
51 +         image = _gtk_quartz_create_image_from_pixbuf (pixbuf);
52 +       
53 +       return image;
54 +}
55 +
56 +
57 +NSImage *
58  _gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf)
59  {
60    CGColorSpaceRef colorspace;
61 Index: gtk/gtkquartz.h
62 ===================================================================
63 --- gtk/gtkquartz.h     (revision 21770)
64 +++ gtk/gtkquartz.h     (working copy)
65 @@ -41,6 +41,7 @@
66                                                     GtkSelectionData *selection_data);
67                         
68  NSImage *_gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf);
69 +NSImage *_gtk_quartz_create_image_from_drawable (GdkDrawable *drawable);
70                             
71  G_END_DECLS
72  
73 Index: gtk/gtktooltip.c
74 ===================================================================
75 --- gtk/gtktooltip.c    (revision 21770)
76 +++ gtk/gtktooltip.c    (working copy)
77 @@ -426,6 +426,7 @@
78  gtk_tooltip_trigger_tooltip_query (GdkDisplay *display)
79  {
80    gint x, y;
81 +  gint rx, ry;
82    GdkWindow *window;
83    GdkEvent event;
84  
85 @@ -434,10 +435,14 @@
86    if (!window)
87      return;
88  
89 +  gdk_window_get_origin (window, &rx, &ry);
90 +
91    event.type = GDK_MOTION_NOTIFY;
92    event.motion.window = window;
93    event.motion.x = x;
94 +  event.motion.x_root = rx + x;
95    event.motion.y = y;
96 +  event.motion.y_root = ry + y;
97    event.motion.is_hint = FALSE;
98  
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)
104 @@ -63,6 +63,11 @@
105                                                  gboolean          create);
106  static void gtk_drag_source_site_destroy        (gpointer           data);
107  
108 +static GtkDragSourceInfo *gtk_drag_get_source_info (GdkDragContext *context,
109 +                                                   gboolean        create);
110 +
111 +extern GdkDragContext *gdk_quartz_drag_source_context(); /* gdk/quartz/gdkdnd-quartz.c */
112 +
113  struct _GtkDragSourceSite 
114  {
115    GdkModifierType    start_button_mask;
116 @@ -89,13 +94,16 @@
117  
118  struct _GtkDragSourceInfo 
119  {
120 +  GtkWidget         *source_widget;
121    GtkWidget         *widget;
122    GtkTargetList     *target_list; /* Targets for drag data */
123    GdkDragAction      possible_actions; /* Actions allowed by source */
124    GdkDragContext    *context;    /* drag context */
125 -
126 +  NSEvent           *nsevent;     /* what started it */
127    gint hot_x, hot_y;             /* Hot spot for drag */
128    GdkPixbuf         *icon_pixbuf;
129 +  gboolean           success;
130 +  gboolean           delete;
131  };
132  
133  struct _GtkDragDestSite 
134 @@ -223,7 +231,9 @@
135                              selection_data,
136                              0, time);
137      }
138 +
139    
140 +  
141    if (site && site->flags & GTK_DEST_DEFAULT_DROP)
142      {
143        gtk_drag_finish (context, 
144 @@ -233,19 +243,24 @@
145      }      
146  }
147  
148 -
149 -GtkWidget *
150 -gtk_drag_get_source_widget (GdkDragContext *context)
151 -{
152 -  return NULL;
153 -}
154 -
155  void 
156  gtk_drag_finish (GdkDragContext *context,
157                  gboolean        success,
158                  gboolean        del,
159                  guint32         time)
160  {
161 +       GtkDragSourceInfo *info;
162 +       GdkDragContext* source_context = gdk_quartz_drag_source_context ();
163 +
164 +       if (source_context) 
165 +         {
166 +            info = gtk_drag_get_source_info (source_context, FALSE);
167 +            if (info) 
168 +              {
169 +                 info->success = success;
170 +                 info->delete = del;
171 +              }
172 +         }
173  }
174  
175  static void
176 @@ -307,6 +322,22 @@
177    g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
178  }
179  
180 +GtkWidget *
181 +gtk_drag_get_source_widget (GdkDragContext *context)
182 +{
183 +  GtkDragSourceInfo *info;
184 +  GdkDragContext* real_source_context = gdk_quartz_drag_source_context();
185 +
186 +  if (!real_source_context)
187 +    return NULL;
188 +
189 +  info = gtk_drag_get_source_info (real_source_context, FALSE);
190 +  if (!info)
191 +     return NULL;
192 +
193 +  return info->source_widget;
194 +}
195 +
196  /*************************************************************
197   * gtk_drag_highlight_expose:
198   *     Callback for expose_event for highlighted widgets.
199 @@ -857,6 +888,8 @@
200         gtk_drag_get_data (widget, context, target, time);
201      }
202    
203 +  /* leave a note for the source-side context about the action chosen */
204 +  
205    g_signal_emit_by_name (widget, "drag-drop",
206                          context, x, y, time, &retval);
207  
208 @@ -1031,6 +1064,45 @@
209    return GDK_NONE;
210  }
211  
212 +static gboolean
213 +gtk_drag_begin_idle (gpointer arg)
214 +{
215 +  GdkDragContext* context = (GdkDragContext*) arg;
216 +  GtkDragSourceInfo* info = gtk_drag_get_source_info (context, FALSE);
217 +  NSWindow *nswindow;
218 +  NSPasteboard *pasteboard;
219 +  GtkDragSourceOwner *owner;
220 +  NSPoint point;
221 +
222 +  g_assert (info != NULL);
223 +
224 +  pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
225 +  owner = [[GtkDragSourceOwner alloc] initWithInfo:info];
226 +
227 +  [pasteboard declareTypes:_gtk_quartz_target_list_to_pasteboard_types (info->target_list) owner:owner];
228 +
229 +  if ((nswindow = get_toplevel_nswindow (info->source_widget)) == NULL)
230 +     return FALSE;
231 +  
232 +  /* Ref the context. It's unreffed when the drag has been aborted */
233 +  g_object_ref (info->context);
234 +
235 +  /* FIXME: If the event isn't a mouse event, use the global cursor position instead */
236 +  point = [info->nsevent locationInWindow];
237 +
238 +  [nswindow dragImage:_gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf)
239 +                   at:point
240 +               offset:NSMakeSize(0, 0)
241 +                event:info->nsevent
242 +           pasteboard:pasteboard
243 +               source:nswindow
244 +            slideBack:YES];
245 +
246 +  [info->nsevent release];
247 +
248 +  return FALSE;
249 +}
250 +
251  static GdkDragContext *
252  gtk_drag_begin_internal (GtkWidget         *widget,
253                          GtkDragSourceSite *site,
254 @@ -1042,16 +1114,13 @@
255    GtkDragSourceInfo *info;
256    GdkDragContext *context;
257    NSWindow *nswindow;
258 -  NSPasteboard *pasteboard;
259 -  GtkDragSourceOwner *owner;
260 -  NSEvent *nsevent;
261 -  NSPoint point;
262  
263    context = gdk_drag_begin (NULL, NULL);
264    context->is_source = TRUE;
265  
266    info = gtk_drag_get_source_info (context, TRUE);
267    
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 @@
273                 GdkPixbuf *pixbuf;
274  
275                 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 1, 1);
276 -               gdk_pixbuf_fill (pixbuf, 0xffffff);
277 -           
278 -               gtk_drag_set_icon_pixbuf (context,
279 -                                         pixbuf,
280 +               gdk_pixbuf_fill (pixbuf, 0xffffff);
281 +
282 +               gtk_drag_set_icon_pixbuf (context,
283 +                                         pixbuf,
284                                           0, 0);
285  
286 -               g_object_unref (pixbuf);
287 +               g_object_unref (pixbuf);
288               }
289             break;
290           case GTK_IMAGE_PIXBUF:
291 @@ -1117,31 +1186,17 @@
292           }
293      }
294  
295 -  gdk_pointer_ungrab (0);
296 -  
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];
302  
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 */
305  
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);
309  
310 -  nswindow = get_toplevel_nswindow (widget);
311 +  gdk_pointer_ungrab (0);
312  
313 -  /* FIXME: If the event isn't a mouse event, use the global cursor position instead */
314 -  nsevent = [nswindow currentEvent];
315 -  point = [nsevent locationInWindow];
316 -
317 -  [nswindow dragImage:_gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf)
318 -                   at:point
319 -               offset:NSMakeSize(0, 0)
320 -                event:nsevent
321 -           pasteboard:pasteboard
322 -               source:nswindow
323 -            slideBack:YES];
324 -
325 -  return info->context;
326 +  return context;
327  }
328  
329  GdkDragContext *
330 @@ -1668,7 +1723,20 @@
331                           gint               hot_x,
332                           gint               hot_y)
333  {
334 -  g_warning ("gtk_drag_set_icon_pixmap is not supported on Mac OS X");
335 +  GdkPixbuf *pixbuf;
336 +  
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));
341 +  
342 +  pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, colormap,
343 +                                        0, 0, /* src */
344 +                                        0, 0, /* dst */
345 +                                        -1, -1);
346 +  
347 +  gtk_drag_set_icon_pixbuf (context, pixbuf, hot_x, hot_y);
348 +  g_object_unref (pixbuf);
349  }
350  
351  /**
352 @@ -1760,6 +1828,9 @@
353    g_signal_emit_by_name (info->widget, "drag-end", 
354                          info->context);
355  
356 +  if (info->source_widget)
357 +    g_object_unref (info->source_widget);
358 +
359    if (info->widget)
360      g_object_unref (info->widget);
361  
362 @@ -1781,6 +1852,10 @@
363  static void
364  gtk_drag_drop_finished (GtkDragSourceInfo *info)
365  {
366 +  if (info->success && info->delete) 
367 +     g_signal_emit_by_name (info->source_widget, "drag-data-delete",
368 +                           info->context);
369 +
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)
377 @@ -112,6 +112,18 @@
378    return ((GdkEventPrivate *) event)->windowing_data;
379  }
380  
381 +/* A category that exposes the protected carbon event for an NSEvent. */
382 +@interface NSEvent (GdkQuartzNSEvent)
383 +- (void *)gdk_quartz_event_ref;
384 +@end 
385 +
386 +@implementation NSEvent (GdkQuartzNSEvent)
387 +- (void *)gdk_quartz_event_ref
388 +{
389 +  return _eventRef;
390 +}
391 +@end
392 +
393  void 
394  _gdk_events_init (void)
395  {
396 @@ -1668,6 +1680,65 @@
397  }
398  
399  static gboolean
400 +_gdk_quartz_possibly_forward_accelerator (NSEvent* nsevent)
401 +{
402 +  /* Special-case menu shortcut events. We create command events for
403 +   * those and forward to the corresponding menu.
404 +   */
405 +  if ((!_gdk_quartz_keyboard_grab_window ||
406 +       (_gdk_quartz_keyboard_grab_window && keyboard_grab_owner_events)) &&
407 +      [nsevent type] == NSKeyDown)
408 +    {
409 +      EventRef event_ref;
410 +      MenuRef menu_ref;
411 +      MenuItemIndex index;
412 +
413 +      event_ref = [nsevent gdk_quartz_event_ref];
414 +      if (IsMenuKeyEvent (NULL, event_ref,
415 +                          kMenuEventQueryOnly, 
416 +                          &menu_ref, &index))
417 +        {
418 +          MenuCommand menu_command;
419 +          HICommand hi_command;
420 +
421 +          if (GetMenuItemCommandID (menu_ref, index, &menu_command) != noErr)
422 +            return FALSE;
423 +   
424 +          hi_command.commandID = menu_command;
425 +          hi_command.menu.menuRef = menu_ref;
426 +          hi_command.menu.menuItemIndex = index;
427 +
428 +          CreateEvent (NULL, kEventClassCommand, kEventCommandProcess, 
429 +                       0, kEventAttributeUserEvent, &event_ref);
430 +          SetEventParameter (event_ref, kEventParamDirectObject, 
431 +                             typeHICommand, 
432 +                             sizeof (HICommand), &hi_command);
433 +
434 +          SendEventToEventTarget (event_ref, GetMenuEventTarget (menu_ref));
435 +
436 +          ReleaseEvent (event_ref);
437 +
438 +          return TRUE;
439 +        }
440 +    }
441 +  return FALSE;
442 +}
443 +
444 +gboolean
445 +gdk_quartz_possibly_forward (GdkEvent* event)
446 +{
447 +  NSEvent *nsevent;
448 +  g_return_val_if_fail (event != NULL, FALSE);
449 +
450 +  nsevent = ((GdkEventPrivate*)event)->windowing_data;
451 +
452 +  if (nsevent)
453 +    return _gdk_quartz_possibly_forward_accelerator (nsevent);
454 +
455 +  return FALSE;
456 +}
457 +
458 +static gboolean
459  gdk_event_translate (NSEvent *nsevent)
460  {
461    NSWindow *nswindow;
462 Index: gdk/quartz/gdkdnd-quartz.c
463 ===================================================================
464 --- gdk/quartz/gdkdnd-quartz.c  (revision 21770)
465 +++ gdk/quartz/gdkdnd-quartz.c  (working copy)
466 @@ -101,6 +101,12 @@
467  
468  GdkDragContext *_gdk_quartz_drag_source_context = NULL;
469  
470 +GdkDragContext*
471 +gdk_quartz_drag_source_context()
472 +{
473 +  return _gdk_quartz_drag_source_context;
474 +}
475 +
476  GdkDragContext * 
477  gdk_drag_begin (GdkWindow     *window,
478                 GList         *targets)
479 Index: gdk/quartz/GdkQuartzWindow.c
480 ===================================================================
481 --- gdk/quartz/GdkQuartzWindow.c        (revision 21770)
482 +++ gdk/quartz/GdkQuartzWindow.c        (working copy)
483 @@ -461,8 +461,29 @@
484  {
485    GdkDragAction result = 0;
486  
487 +  /* GDK and Quartz drag operations do not map 1:1.
488 +     This mapping represents about the best that we
489 +     can come up.
490 +
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
499 +     same)
500 +   */
501 +
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;
510  
511    return result;
512  }
513 @@ -474,6 +495,10 @@
514  
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;
521  
522    return result;
523  }
524 @@ -485,6 +510,7 @@
525  
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;
529  }
530  
531  - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
532 @@ -510,6 +536,10 @@
533  
534  - (void)draggingEnded:(id <NSDraggingInfo>)sender
535  {
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;
539 +
540    if (current_context)
541      g_object_unref (current_context);
542    current_context = NULL;