[gtk+/gtk-2-24] Decouple GdkWindowCache life-cycle from GdkX11DragContext
- From: Adel Gadllah <agadllah src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-2-24] Decouple GdkWindowCache life-cycle from GdkX11DragContext
- Date: Wed, 5 Jan 2011 16:43:18 +0000 (UTC)
commit 644f25c4971bd8732a8738914776c7028b0bdfea
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Jan 5 17:37:37 2011 +0100
Decouple GdkWindowCache life-cycle from GdkX11DragContext
By making window caches refcounted. This fixes problems with leaking
drag contexts, as experienced in
https://bugzilla.gnome.org/show_bug.cgi?id=637691
and
https://bugzilla.gnome.org/show_bug.cgi?id=144324
Based on a patch by drago01 gmail com
gdk/x11/gdkdnd-x11.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 52 insertions(+), 5 deletions(-)
---
diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c
index 06edc03..90d85a9 100644
--- a/gdk/x11/gdkdnd-x11.c
+++ b/gdk/x11/gdkdnd-x11.c
@@ -68,6 +68,7 @@ typedef struct {
GHashTable *child_hash;
guint old_event_mask;
GdkScreen *screen;
+ gint ref_count;
} GdkWindowCache;
/* Structure that holds information about a drag in progress.
@@ -103,7 +104,9 @@ struct _GdkDragContextPrivateX11 {
/* Forward declarations */
-static void gdk_window_cache_destroy (GdkWindowCache *cache);
+static GdkWindowCache *gdk_window_cache_get (GdkScreen *screen);
+static GdkWindowCache *gdk_window_cache_ref (GdkWindowCache *cache);
+static void gdk_window_cache_unref (GdkWindowCache *cache);
static void motif_read_target_table (GdkDisplay *display);
@@ -137,6 +140,7 @@ static void xdnd_manage_source_filter (GdkDragContext *context,
static void gdk_drag_context_finalize (GObject *object);
static GList *contexts;
+static GSList *window_caches;
static const struct {
const char *atom_name;
@@ -197,9 +201,8 @@ gdk_drag_context_finalize (GObject *object)
if (context->dest_window)
g_object_unref (context->dest_window);
- for (tmp_list = private->window_caches; tmp_list; tmp_list = tmp_list->next)
- gdk_window_cache_destroy (tmp_list->data);
- g_slist_free (private->window_caches);
+ g_slist_free_full (private->window_caches, (GDestroyNotify)gdk_window_cache_unref);
+ private->window_caches = NULL;
contexts = g_list_remove (contexts, context);
@@ -531,6 +534,7 @@ gdk_window_cache_new (GdkScreen *screen)
result->children = NULL;
result->child_hash = g_hash_table_new (g_direct_hash, NULL);
result->screen = screen;
+ result->ref_count = 1;
XGetWindowAttributes (xdisplay, GDK_WINDOW_XWINDOW (root_window), &xwa);
result->old_event_mask = xwa.your_event_mask;
@@ -592,6 +596,49 @@ gdk_window_cache_new (GdkScreen *screen)
return result;
}
+static GdkWindowCache *
+gdk_window_cache_ref (GdkWindowCache *cache)
+{
+ cache->ref_count += 1;
+
+ return cache;
+}
+
+static void
+gdk_window_cache_unref (GdkWindowCache *cache)
+{
+ g_assert (cache->ref_count > 0);
+
+ cache->ref_count -= 1;
+
+ if (cache->ref_count == 0)
+ {
+ window_caches = g_slist_remove (window_caches, cache);
+ gdk_window_cache_destroy (cache);
+ }
+}
+
+GdkWindowCache *
+gdk_window_cache_get (GdkScreen *screen)
+{
+ GSList *list;
+ GdkWindowCache *cache;
+
+ for (list = window_caches; list; list = list->next)
+ {
+ cache = list->data;
+ if (cache->screen == screen)
+ return gdk_window_cache_ref (cache);
+ }
+
+ cache = gdk_window_cache_new (screen);
+
+ window_caches = g_slist_prepend (window_caches, cache);
+
+ return cache;
+}
+
+
static void
gdk_window_cache_destroy (GdkWindowCache *cache)
{
@@ -3302,7 +3349,7 @@ drag_context_find_window_cache (GdkDragContext *context,
return cache;
}
- cache = gdk_window_cache_new (screen);
+ cache = gdk_window_cache_get (screen);
private->window_caches = g_slist_prepend (private->window_caches, cache);
return cache;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]