diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index ba4ad63a3b..e9c5512a21 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -4751,17 +4751,21 @@ _gdk_window_process_updates_recurse (GdkWindow *window, GdkWindowObject *child; GdkRegion *child_region; GdkRectangle r; - GList *l; + GList *l, *children; if (gdk_region_empty (expose_region)) return; + /* Make this reentrancy safe for expose handlers freeing windows */ + children = g_list_copy (private->children); + g_list_foreach (children, g_object_ref, NULL); + /* Iterate over children, starting at topmost */ - for (l = private->children; l != NULL; l = l->next) + for (l = children; l != NULL; l = l->next) { child = l->data; - if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) + if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) continue; /* Ignore offscreen children, as they don't draw in their parent and @@ -4799,6 +4803,9 @@ _gdk_window_process_updates_recurse (GdkWindow *window, gdk_region_destroy (child_region); } + g_list_foreach (children, g_object_unref, NULL); + g_list_free (children); + if (!gdk_region_empty (expose_region)) { if (private->event_mask & GDK_EXPOSURE_MASK)