|
|
a6b8b6 |
From c212cb8f32c02cf2fe691372b753d334f6e25d69 Mon Sep 17 00:00:00 2001
|
|
|
a6b8b6 |
From: Marek Kasik <mkasik@redhat.com>
|
|
|
a6b8b6 |
Date: Mon, 16 Dec 2013 18:04:14 +0100
|
|
|
a6b8b6 |
Subject: [PATCH 1/2] gdkwindow: Handle references in "update_windows" list
|
|
|
a6b8b6 |
correctly
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
Since update_windows list is a static variable in GdkWindow.c which
|
|
|
a6b8b6 |
contains pointers to windows which needs to be updated, it can happen
|
|
|
a6b8b6 |
that it contains a pointer to a window even after quit from a gtk_main().
|
|
|
a6b8b6 |
If another gtk_main() is called in the same process it tries to process
|
|
|
a6b8b6 |
windows in the list which leads to a crash.
|
|
|
a6b8b6 |
Correct reference count handling of added windows prevents such applications
|
|
|
a6b8b6 |
from crash.
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
https://bugzilla.gnome.org/show_bug.cgi?id=711552
|
|
|
a6b8b6 |
---
|
|
|
a6b8b6 |
gdk/gdkwindow.c | 19 ++++++++++++-------
|
|
|
a6b8b6 |
1 file changed, 12 insertions(+), 7 deletions(-)
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
|
|
|
a6b8b6 |
index f5f0339..0f33fb0 100644
|
|
|
a6b8b6 |
--- a/gdk/gdkwindow.c
|
|
|
a6b8b6 |
+++ b/gdk/gdkwindow.c
|
|
|
a6b8b6 |
@@ -5267,7 +5267,7 @@ gdk_window_add_update_window (GdkWindow *window)
|
|
|
a6b8b6 |
prev = tmp;
|
|
|
a6b8b6 |
}
|
|
|
a6b8b6 |
/* here, tmp got advanced past all lower stacked siblings */
|
|
|
a6b8b6 |
- tmp = g_slist_prepend (tmp, window);
|
|
|
a6b8b6 |
+ tmp = g_slist_prepend (tmp, g_object_ref (window));
|
|
|
a6b8b6 |
if (prev)
|
|
|
a6b8b6 |
prev->next = tmp;
|
|
|
a6b8b6 |
else
|
|
|
a6b8b6 |
@@ -5280,7 +5280,7 @@ gdk_window_add_update_window (GdkWindow *window)
|
|
|
a6b8b6 |
*/
|
|
|
a6b8b6 |
if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
|
|
|
a6b8b6 |
{
|
|
|
a6b8b6 |
- tmp = g_slist_prepend (tmp, window);
|
|
|
a6b8b6 |
+ tmp = g_slist_prepend (tmp, g_object_ref (window));
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
if (prev)
|
|
|
a6b8b6 |
prev->next = tmp;
|
|
|
a6b8b6 |
@@ -5294,7 +5294,7 @@ gdk_window_add_update_window (GdkWindow *window)
|
|
|
a6b8b6 |
*/
|
|
|
a6b8b6 |
if (! tmp->next && has_ancestor_in_list)
|
|
|
a6b8b6 |
{
|
|
|
a6b8b6 |
- tmp = g_slist_append (tmp, window);
|
|
|
a6b8b6 |
+ tmp = g_slist_append (tmp, g_object_ref (window));
|
|
|
a6b8b6 |
return;
|
|
|
a6b8b6 |
}
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
@@ -5305,13 +5305,20 @@ gdk_window_add_update_window (GdkWindow *window)
|
|
|
a6b8b6 |
* hierarchy than what is already in the list) or the list is
|
|
|
a6b8b6 |
* empty, prepend
|
|
|
a6b8b6 |
*/
|
|
|
a6b8b6 |
- update_windows = g_slist_prepend (update_windows, window);
|
|
|
a6b8b6 |
+ update_windows = g_slist_prepend (update_windows, g_object_ref (window));
|
|
|
a6b8b6 |
}
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
static void
|
|
|
a6b8b6 |
gdk_window_remove_update_window (GdkWindow *window)
|
|
|
a6b8b6 |
{
|
|
|
a6b8b6 |
- update_windows = g_slist_remove (update_windows, window);
|
|
|
a6b8b6 |
+ GSList *link;
|
|
|
a6b8b6 |
+
|
|
|
a6b8b6 |
+ link = g_slist_find (update_windows, window);
|
|
|
a6b8b6 |
+ if (link != NULL)
|
|
|
a6b8b6 |
+ {
|
|
|
a6b8b6 |
+ update_windows = g_slist_delete_link (update_windows, link);
|
|
|
a6b8b6 |
+ g_object_unref (window);
|
|
|
a6b8b6 |
+ }
|
|
|
a6b8b6 |
}
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
static gboolean
|
|
|
a6b8b6 |
@@ -5687,8 +5694,6 @@ gdk_window_process_all_updates (void)
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
_gdk_windowing_before_process_all_updates ();
|
|
|
a6b8b6 |
|
|
|
a6b8b6 |
- g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
|
|
|
a6b8b6 |
-
|
|
|
a6b8b6 |
while (tmp_list)
|
|
|
a6b8b6 |
{
|
|
|
a6b8b6 |
GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
|
|
|
a6b8b6 |
--
|
|
|
a6b8b6 |
1.8.4.2
|
|
|
a6b8b6 |
|