[87416] trunk/dports/gnome/gtk2

ryandesign at macports.org ryandesign at macports.org
Sun Nov 20 14:34:58 PST 2011


Revision: 87416
          http://trac.macports.org/changeset/87416
Author:   ryandesign at macports.org
Date:     2011-11-20 14:34:53 -0800 (Sun, 20 Nov 2011)
Log Message:
-----------
gtk2: fix drag and drop crash; see #32152

Modified Paths:
--------------
    trunk/dports/gnome/gtk2/Portfile

Added Paths:
-----------
    trunk/dports/gnome/gtk2/files/658722.diff
    trunk/dports/gnome/gtk2/files/664238.diff

Modified: trunk/dports/gnome/gtk2/Portfile
===================================================================
--- trunk/dports/gnome/gtk2/Portfile	2011-11-20 21:15:16 UTC (rev 87415)
+++ trunk/dports/gnome/gtk2/Portfile	2011-11-20 22:34:53 UTC (rev 87416)
@@ -7,6 +7,7 @@
 
 name                gtk2
 version             2.24.8
+revision            1
 set branch          [join [lrange [split ${version} .] 0 1] .]
 categories          gnome x11
 license             LGPL-2+
@@ -34,7 +35,9 @@
                     sha256  ac2325a65312922a6722a7c02a389f3f4072d79e13131485cc7b7226e2537043
 
 patchfiles          patch-gtk-builder-convert.diff patch-aliases.diff \
-                    patch-tests_Makefile.in.diff
+                    patch-tests_Makefile.in.diff \
+                    658722.diff \
+                    664238.diff
 
 depends_build       port:pkgconfig \
                     port:perl5

Added: trunk/dports/gnome/gtk2/files/658722.diff
===================================================================
--- trunk/dports/gnome/gtk2/files/658722.diff	                        (rev 0)
+++ trunk/dports/gnome/gtk2/files/658722.diff	2011-11-20 22:34:53 UTC (rev 87416)
@@ -0,0 +1,270 @@
+From dcd9ab00c64a1df63fd5fa58c2ca25efd9b3e09e Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls at ceridwen.us>
+Date: Sat, 24 Sep 2011 18:14:09 -0700
+Subject: [PATCH 06/15] Bug 658722 - Drag and Drop sometimes stops working
+
+First, rather than assuming that there's already an event queued up if
+_gdk_quartz_drag_source_context isn't NULL, assume that it just didn't get
+cleaned up the last time it ran and abort it.
+
+This naturally requires implementing gdk_quartz_drag_abort(), so remove the
+code from [GdkQuartzNSWindow draggedImage:endedAt:operation:] and move it to
+gdkdnd_quartz.c as static void gdk_quartz_drag_end(). Implement both
+gdk_quartz_drag_drop() and gdk_quartz_drag_abort() by calling
+gdk_quartz_drag_end().
+
+Next, try to get rid of the memory cycle between gtk_drag_source_info.context
+and _gdk_quartz_drag_source_context (which carries the GtkQuartzDragSourceInfo
+struct as qdata). Replace gtk_drag_source_clear_info() by using a
+g_object_set_qdata_full() for context in gtk_drag_get_source_context, calling
+gtk_drag_source_info_destroy() as the destructor. This eliminates the need to
+queue a cleanup idle event. I use g_object_run_dispose() on
+_gtk_quartz_drag_source_context to force the deletion of the info stored as
+qdata, which in turn unrefs the info->context pointer. Ordinarily this gets
+fired off from draggedImage:endedAt:operation:, meaning that the special
+dragging CFRunLoop is complete and NSEvents are again flowing, so queuing a
+cleanup event isn't necessary. The advantage is that it can also be run from
+gdk_drag_abort, so if Gdk thinks there's a drag but CF doesn't all of the
+memory still gets cleaned up.
+---
+ gdk/quartz/GdkQuartzWindow.c |   16 +-------
+ gdk/quartz/gdkdnd-quartz.c   |   35 +++++++++++++--
+ gtk/gtkdnd-quartz.c          |   96 ++++++++++++++++-------------------------
+ 3 files changed, 69 insertions(+), 78 deletions(-)
+
+--- gdk/quartz/GdkQuartzWindow.c.orig
++++ gdk/quartz/GdkQuartzWindow.c
+@@ -560,21 +560,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
+ 
+ - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
+ {
+-  GdkEvent event;
+-
+-  g_assert (_gdk_quartz_drag_source_context != NULL);
+-
+-  event.dnd.type = GDK_DROP_FINISHED;
+-  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+-  event.dnd.send_event = FALSE;
+-  event.dnd.context = _gdk_quartz_drag_source_context;
+-
+-  (*_gdk_event_func) (&event, _gdk_event_data);
+-
+-  g_object_unref (event.dnd.window);
+-
+-  g_object_unref (_gdk_quartz_drag_source_context);
+-  _gdk_quartz_drag_source_context = NULL;
++  gdk_drag_drop (_gdk_quartz_drag_source_context, (guint32)g_get_real_time());
+ }
+ 
+ @end
+--- gdk/quartz/gdkdnd-quartz.c.orig
++++ gdk/quartz/gdkdnd-quartz.c
+@@ -111,11 +111,20 @@ GdkDragContext *
+ gdk_drag_begin (GdkWindow     *window,
+ 		GList         *targets)
+ {
+-  g_assert (_gdk_quartz_drag_source_context == NULL);
++  if (_gdk_quartz_drag_source_context != NULL)
++    {
++      /* Something is amiss with the existing drag, so log a message
++	 and abort it */
++      g_warning ("Drag begun with existing context; aborting the preexisting drag");
++      gdk_drag_abort (_gdk_quartz_drag_source_context,
++		      (guint32)g_get_real_time ());
++    }
++
+   
+   /* Create fake context */
+   _gdk_quartz_drag_source_context = gdk_drag_context_new ();
+   _gdk_quartz_drag_source_context->is_source = TRUE;
++  _gdk_quartz_drag_source_context->source_window = window;
+   
+   return _gdk_quartz_drag_source_context;
+ }
+@@ -155,20 +164,36 @@ gdk_drag_find_window_for_screen (GdkDragContext  *context,
+   /* FIXME: Implement */
+ }
+ 
++static void
++gdk_quartz_drag_end (GdkDragContext *context)
++{
++  GdkEvent event;
++
++  g_assert (context != NULL);
++  event.dnd.type = GDK_DROP_FINISHED;
++  event.dnd.window = g_object_ref (context->source_window);
++  event.dnd.send_event = FALSE;
++  event.dnd.context = context;
++
++  (*_gdk_event_func) (&event, _gdk_event_data);
++
++  g_object_run_dispose (_gdk_quartz_drag_source_context);
++  _gdk_quartz_drag_source_context = NULL;
++}
++
+ void
+ gdk_drag_drop (GdkDragContext *context,
+ 	       guint32         time)
+ {
+-  /* FIXME: Implement */
++  gdk_quartz_drag_end (context);
+ }
+ 
+ void
+ gdk_drag_abort (GdkDragContext *context,
+ 		guint32         time)
+ {
+-  g_return_if_fail (context != NULL);
+-  
+-  /* FIXME: Implement */
++  g_warning ("Gdk-quartz-drag-drop, aborting\n");
++  gdk_quartz_drag_end (context);
+ }
+ 
+ void             
+diff --git a/gtk/gtkdnd-quartz.c b/gtk/gtkdnd-quartz.c
+index 5688568..be92a22 100644
+--- gtk/gtkdnd-quartz.c.orig
++++ gtk/gtkdnd-quartz.c
+@@ -269,6 +269,39 @@ gtk_drag_dest_info_destroy (gpointer data)
+   g_free (info);
+ }
+ 
++static void
++gtk_drag_source_info_destroy (GtkDragSourceInfo *info)
++{
++  NSPasteboard *pasteboard;
++  NSAutoreleasePool *pool;
++
++  if (info->icon_pixbuf)
++    g_object_unref (info->icon_pixbuf);
++
++  g_signal_emit_by_name (info->widget, "drag-end", 
++			 info->context);
++
++  if (info->source_widget)
++    g_object_unref (info->source_widget);
++
++  if (info->widget)
++    g_object_unref (info->widget);
++
++  gtk_target_list_unref (info->target_list);
++
++  pool = [[NSAutoreleasePool alloc] init];
++
++  /* Empty the pasteboard, so that it will not accidentally access
++   * info->context after it has been destroyed.
++   */
++  pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard];
++  [pasteboard declareTypes: nil owner: nil];
++
++  [pool release];
++
++  g_free (info);
++}
++
+ static GtkDragDestInfo *
+ gtk_drag_get_dest_info (GdkDragContext *context,
+ 			gboolean        create)
+@@ -308,18 +341,14 @@ gtk_drag_get_source_info (GdkDragContext *context,
+     {
+       info = g_new0 (GtkDragSourceInfo, 1);
+       info->context = context;
+-      g_object_set_qdata (G_OBJECT (context), dest_info_quark, info);
++      g_object_ref (info->context);
++      g_object_set_qdata_full (G_OBJECT (context), dest_info_quark,
++			       info, gtk_drag_source_info_destroy);
+     }
+ 
+   return info;
+ }
+ 
+-static void
+-gtk_drag_clear_source_info (GdkDragContext *context)
+-{
+-  g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
+-}
+-
+ GtkWidget *
+ gtk_drag_get_source_widget (GdkDragContext *context)
+ {
+@@ -1089,7 +1118,8 @@ gtk_drag_begin_idle (gpointer arg)
+   [owner release];
+   [types release];
+ 
+-  if ((nswindow = get_toplevel_nswindow (info->source_widget)) == NULL)
++  if (info->source_widget == NULL
++      || (nswindow = get_toplevel_nswindow (info->source_widget)) == NULL)
+      return FALSE;
+   
+   /* Ref the context. It's unreffed when the drag has been aborted */
+@@ -1108,7 +1138,6 @@ gtk_drag_begin_idle (gpointer arg)
+                source:nswindow
+             slideBack:YES];
+ 
+-  [info->nsevent release];
+   [drag_image release];
+ 
+   [pool release];
+@@ -1833,61 +1862,12 @@ gtk_drag_set_default_icon (GdkColormap   *colormap,
+ }
+ 
+ static void
+-gtk_drag_source_info_destroy (GtkDragSourceInfo *info)
+-{
+-  NSPasteboard *pasteboard;
+-  NSAutoreleasePool *pool;
+-
+-  if (info->icon_pixbuf)
+-    g_object_unref (info->icon_pixbuf);
+-
+-  g_signal_emit_by_name (info->widget, "drag-end", 
+-			 info->context);
+-
+-  if (info->source_widget)
+-    g_object_unref (info->source_widget);
+-
+-  if (info->widget)
+-    g_object_unref (info->widget);
+-
+-  gtk_target_list_unref (info->target_list);
+-
+-  pool = [[NSAutoreleasePool alloc] init];
+-
+-  /* Empty the pasteboard, so that it will not accidentally access
+-   * info->context after it has been destroyed.
+-   */
+-  pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard];
+-  [pasteboard declareTypes: nil owner: nil];
+-
+-  [pool release];
+-
+-  gtk_drag_clear_source_info (info->context);
+-  g_object_unref (info->context);
+-
+-  g_free (info);
+-  info = NULL;
+-}
+-
+-static gboolean
+-drag_drop_finished_idle_cb (gpointer data)
+-{
+-  gtk_drag_source_info_destroy (data);
+-  return FALSE;
+-}
+-
+-static void
+ gtk_drag_drop_finished (GtkDragSourceInfo *info)
+ {
+   if (info->success && info->delete)
+     g_signal_emit_by_name (info->source_widget, "drag-data-delete",
+                            info->context);
+ 
+-  /* Workaround for the fact that the NS API blocks until the drag is
+-   * over. This way the context is still valid when returning from
+-   * drag_begin, even if it will still be quite useless. See bug #501588.
+-  */
+-  g_idle_add (drag_drop_finished_idle_cb, info);
+ }
+ 
+ /*************************************************************

Added: trunk/dports/gnome/gtk2/files/664238.diff
===================================================================
--- trunk/dports/gnome/gtk2/files/664238.diff	                        (rev 0)
+++ trunk/dports/gnome/gtk2/files/664238.diff	2011-11-20 22:34:53 UTC (rev 87416)
@@ -0,0 +1,24 @@
+From ede7c10f00ca07bfcf129bb91af533a046c76e0f Mon Sep 17 00:00:00 2001
+From: John Ralls <jralls at ceridwen.us>
+Date: Sat, 19 Nov 2011 11:33:28 -0800
+Subject: [PATCH] [Bug 664238] GTK apps crash when dragging something
+
+Corrects a bad condition in a test in fadc82ad.
+---
+ gtk/gtkquartz.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+--- gtk/gtkquartz.c.orig
++++ gtk/gtkquartz.c
+@@ -39,7 +39,7 @@ _gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf)
+ 
+   pixbuf_width = gdk_pixbuf_get_width (pixbuf);
+   pixbuf_height = gdk_pixbuf_get_height (pixbuf);
+-  g_return_val_if_fail (pixbuf_width == 0 && pixbuf_height == 0, NULL);
++  g_return_val_if_fail (pixbuf_width != 0 && pixbuf_height != 0, NULL);
+   rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+   has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ 
+-- 
+1.7.6.3.dirty
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20111120/a064bbcc/attachment.html>


More information about the macports-changes mailing list