gdkwindow: Handle references in "update_windows" list correctly
Since update_windows list is a static variable in GdkWindow.c which contains pointers to windows which needs to be updated, it can happen that it contains a pointer to a window even after quit from a gtk_main(). If another gtk_main() is called in the same process it tries to process windows in the list which leads to a crash. Correct reference count handling of added windows prevents such applications from crash. https://bugzilla.gnome.org/show_bug.cgi?id=711552
This commit is contained in:
parent
bfd27445e6
commit
1b032b18cc
@ -3252,7 +3252,7 @@ gdk_window_add_update_window (GdkWindow *window)
|
|||||||
prev = tmp;
|
prev = tmp;
|
||||||
}
|
}
|
||||||
/* here, tmp got advanced past all lower stacked siblings */
|
/* here, tmp got advanced past all lower stacked siblings */
|
||||||
tmp = g_slist_prepend (tmp, window);
|
tmp = g_slist_prepend (tmp, g_object_ref (window));
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->next = tmp;
|
prev->next = tmp;
|
||||||
else
|
else
|
||||||
@ -3265,7 +3265,7 @@ gdk_window_add_update_window (GdkWindow *window)
|
|||||||
*/
|
*/
|
||||||
if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
|
if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
|
||||||
{
|
{
|
||||||
tmp = g_slist_prepend (tmp, window);
|
tmp = g_slist_prepend (tmp, g_object_ref (window));
|
||||||
|
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->next = tmp;
|
prev->next = tmp;
|
||||||
@ -3279,7 +3279,7 @@ gdk_window_add_update_window (GdkWindow *window)
|
|||||||
*/
|
*/
|
||||||
if (! tmp->next && has_ancestor_in_list)
|
if (! tmp->next && has_ancestor_in_list)
|
||||||
{
|
{
|
||||||
tmp = g_slist_append (tmp, window);
|
tmp = g_slist_append (tmp, g_object_ref (window));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3290,13 +3290,20 @@ gdk_window_add_update_window (GdkWindow *window)
|
|||||||
* hierarchy than what is already in the list) or the list is
|
* hierarchy than what is already in the list) or the list is
|
||||||
* empty, prepend
|
* empty, prepend
|
||||||
*/
|
*/
|
||||||
update_windows = g_slist_prepend (update_windows, window);
|
update_windows = g_slist_prepend (update_windows, g_object_ref (window));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_window_remove_update_window (GdkWindow *window)
|
gdk_window_remove_update_window (GdkWindow *window)
|
||||||
{
|
{
|
||||||
update_windows = g_slist_remove (update_windows, window);
|
GSList *link;
|
||||||
|
|
||||||
|
link = g_slist_find (update_windows, window);
|
||||||
|
if (link != NULL)
|
||||||
|
{
|
||||||
|
update_windows = g_slist_delete_link (update_windows, link);
|
||||||
|
g_object_unref (window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -3579,8 +3586,6 @@ gdk_window_process_all_updates (void)
|
|||||||
|
|
||||||
before_process_all_updates ();
|
before_process_all_updates ();
|
||||||
|
|
||||||
g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
|
|
||||||
|
|
||||||
while (tmp_list)
|
while (tmp_list)
|
||||||
{
|
{
|
||||||
GdkWindow *window = tmp_list->data;
|
GdkWindow *window = tmp_list->data;
|
||||||
|
Loading…
Reference in New Issue
Block a user