surface-actor-x11: Bind the surface actor resources to window actor life

X11 actors need to release the server data (pixmap and damage) before the
display is closed.
During the close phase all the windows are unmanaged and this causes the window
actors to be removed from the compositor, unsetting their actor surface.

However, in case a window is animating the surface might not be destroyed until
the animation is completed and a reference to it kept around by gjs in the shell
case. By the way, per commit 7718e67f all window actors (even the animating
ones) are destroyed before the display is closed, but this is not true for the
child surface, because the parent window will just unref it, leaving it around
if reffed somewhere else. This is fine for wayland surfaces, but not for X11
ones which are bound to server-side pixmaps.

So, connect to the parent MetaWindowActor "destroy" signal, releasing the x11
resources that implies detaching the pixmap (unsetting the texture) and removing
the damages.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/629
https://gitlab.gnome.org/GNOME/mutter/merge_requests/660
This commit is contained in:
Marco Trevisan (Treviño) 2019-06-28 11:45:22 +02:00
parent d7d97f2477
commit de97b54595

View File

@ -32,6 +32,7 @@
#include "cogl/winsys/cogl-texture-pixmap-x11.h" #include "cogl/winsys/cogl-texture-pixmap-x11.h"
#include "compositor/meta-cullable.h" #include "compositor/meta-cullable.h"
#include "compositor/meta-shaped-texture-private.h" #include "compositor/meta-shaped-texture-private.h"
#include "compositor/meta-window-actor-private.h"
#include "core/window-private.h" #include "core/window-private.h"
#include "meta/meta-x11-errors.h" #include "meta/meta-x11-errors.h"
#include "x11/meta-x11-display-private.h" #include "x11/meta-x11-display-private.h"
@ -347,13 +348,19 @@ meta_surface_actor_x11_is_unredirected (MetaSurfaceActor *actor)
return self->unredirected; return self->unredirected;
} }
static void
release_x11_resources (MetaSurfaceActorX11 *self)
{
detach_pixmap (self);
free_damage (self);
}
static void static void
meta_surface_actor_x11_dispose (GObject *object) meta_surface_actor_x11_dispose (GObject *object)
{ {
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object); MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object);
detach_pixmap (self); release_x11_resources (self);
free_damage (self);
G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object);
} }
@ -407,8 +414,7 @@ window_decorated_notify (MetaWindow *window,
{ {
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data); MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data);
detach_pixmap (self); release_x11_resources (self);
free_damage (self);
create_damage (self); create_damage (self);
} }
@ -445,6 +451,10 @@ meta_surface_actor_x11_new (MetaWindow *window)
g_signal_connect_object (self->window, "notify::decorated", g_signal_connect_object (self->window, "notify::decorated",
G_CALLBACK (window_decorated_notify), self, 0); G_CALLBACK (window_decorated_notify), self, 0);
g_signal_connect_object (meta_window_actor_from_window (window), "destroy",
G_CALLBACK (release_x11_resources), self,
G_CONNECT_SWAPPED);
self->unredirected = FALSE; self->unredirected = FALSE;
sync_unredirected (self); sync_unredirected (self);