From 6a0d317866ff8f8c3e7efefa44f982f7bcbbc3b8 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 23 Jan 2009 20:08:39 +0100 Subject: [PATCH] Keep track of the impl windows wrapper directly with a ref This is needed so that the ->wrapper of the impl window doesn't go away while there are virtual windows referencing the impl window. --- gdk/gdkwindow.c | 37 +++++++++++++++++++++++++++---------- gdk/gdkwindow.h | 4 ++++ gdk/x11/gdkwindow-x11.c | 2 ++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index b203d94cd9..2ce4e0a7d1 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -389,6 +389,12 @@ gdk_window_finalize (GObject *object) obj->impl = NULL; } + if (obj->impl_window != obj) + { + g_object_unref (obj->impl_window); + obj->impl_window = NULL; + } + if (obj->shape) gdk_region_destroy (obj->shape); @@ -410,10 +416,7 @@ gdk_window_is_offscreen (GdkWindowObject *window) static GdkWindowObject * gdk_window_get_impl_window (GdkWindowObject *window) { - while (window->parent != NULL && window->parent->impl == window->impl) - window = window->parent; - - return window; + return window->impl_window; } GdkWindow * @@ -425,7 +428,7 @@ _gdk_window_get_impl_window (GdkWindow *window) static gboolean gdk_window_has_impl (GdkWindowObject *window) { - return window->parent == NULL || window->parent->impl != window->impl; + return window->impl_window == window; } gboolean @@ -437,7 +440,7 @@ _gdk_window_has_impl (GdkWindow *window) static gboolean gdk_window_has_no_impl (GdkWindowObject *window) { - return window->parent->impl == window->impl; + return window->impl_window; } static void @@ -917,6 +920,7 @@ gdk_window_new (GdkWindow *parent, if (private->window_type == GDK_WINDOW_OFFSCREEN) { _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask); + private->impl_window = private; } else if (native) { @@ -927,6 +931,7 @@ gdk_window_new (GdkWindow *parent, /* Create the impl */ _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask); + private->impl_window = private; /* This will put the native window topmost in the native parent, which may * be wrong wrt other native windows in the non-native hierarchy, so restack */ @@ -941,7 +946,8 @@ gdk_window_new (GdkWindow *parent, } else { - private->impl = g_object_ref (private->parent->impl); + private->impl_window = g_object_ref (private->parent->impl_window); + private->impl = g_object_ref (private->impl_window->impl); } recompute_visible_regions (private, TRUE, FALSE); @@ -979,14 +985,23 @@ is_parent_of (GdkWindow *parent, static void change_impl (GdkWindowObject *private, + GdkWindowObject *impl_window, GdkDrawable *new) { GList *l; GdkWindowObject *child; GdkDrawable *old_impl; + GdkWindowObject *old_impl_window; old_impl = private->impl; + old_impl_window = private->impl_window; + if (private != impl_window) + private->impl_window = g_object_ref (impl_window); + else + private->impl_window = private; private->impl = g_object_ref (new); + if (old_impl_window != private) + g_object_unref (old_impl_window); g_object_unref (old_impl); for (l = private->children; l != NULL; l = l->next) @@ -994,7 +1009,7 @@ change_impl (GdkWindowObject *private, child = l->data; if (child->impl == old_impl) - change_impl (child, new); + change_impl (child, impl_window, new); } } @@ -1113,7 +1128,9 @@ gdk_window_reparent (GdkWindow *window, gdk_window_hide (window); do_reparent_to_impl = TRUE; - change_impl (private, new_parent_private->impl); + change_impl (private, + new_parent_private->impl_window, + new_parent_private->impl); } /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like @@ -1259,7 +1276,7 @@ gdk_window_set_has_native (GdkWindow *window, gboolean has_native) new_impl = private->impl; private->impl = old_impl; - change_impl (private, new_impl); + change_impl (private, private, new_impl); /* Native window creation will put the native window topmost in the * native parent, which may be wrong wrt other native windows in the diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 0956dd693e..3b3683fa9b 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -326,6 +326,10 @@ struct _GdkWindowObject GdkWindowRedirect *redirect; const GdkOffscreenChildHooks *offscreen_hooks; + /* The GdkWindowObject that has the impl, ref:ed if another window. + * This ref is required to keep the wrapper of the impl window alive + * for as long as any GdkWindow references the impl. */ + GdkWindowObject *impl_window; int abs_x, abs_y; /* Absolute offset in impl */ gint width, height; guint32 clip_tag; diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 8438ddfac6..685e72fb92 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -441,6 +441,7 @@ _gdk_windowing_window_init (GdkScreen * screen) private = (GdkWindowObject *) screen_x11->root_window; private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl_window = private; impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); @@ -916,6 +917,7 @@ gdk_window_foreign_new_for_display (GdkDisplay *display, private = (GdkWindowObject *) window; private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl_window = private; impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);