mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-11 03:10:09 +00:00
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.
This commit is contained in:
parent
cf54a2c68e
commit
6a0d317866
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user