[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