From 3d618d5e4579de058c4c1dac2b58187820c49f98 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Fri, 9 Dec 2022 21:47:32 +0100 Subject: [PATCH] window-actor/wayland: Ignore unmapped subsurfaces in direct scanout check Clients expect us to ignore them, thus do so. Right now, if the topmost subsurface is an unmapped subsurface, it will fail the `meta_surface_actor_is_opaque()` check if it was never mapped before. Further more, unmapped subsurfaces would wrongly disable our "only one surface and fullscreen" optimization. Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2550 Part-of: --- src/compositor/meta-window-actor-wayland.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/compositor/meta-window-actor-wayland.c b/src/compositor/meta-window-actor-wayland.c index 7ed5163d2..abf433a4e 100644 --- a/src/compositor/meta-window-actor-wayland.c +++ b/src/compositor/meta-window-actor-wayland.c @@ -298,8 +298,10 @@ meta_window_actor_wayland_get_scanout_candidate (MetaWindowActor *actor) MetaWindowActorWayland *self = META_WINDOW_ACTOR_WAYLAND (actor); ClutterActor *surface_container = CLUTTER_ACTOR (self->surface_container); ClutterActor *child_actor; - MetaSurfaceActor *topmost_surface_actor; + ClutterActorIter iter; + MetaSurfaceActor *topmost_surface_actor = NULL; MetaWindow *window; + int n_mapped_surfaces = 0; if (clutter_actor_get_last_child (CLUTTER_ACTOR (self)) != surface_container) { @@ -308,20 +310,26 @@ meta_window_actor_wayland_get_scanout_candidate (MetaWindowActor *actor) return FALSE; } - child_actor = clutter_actor_get_last_child (surface_container); - if (!child_actor) + clutter_actor_iter_init (&iter, surface_container); + while (clutter_actor_iter_next (&iter, &child_actor)) + { + if (!clutter_actor_is_mapped (child_actor)) + continue; + + topmost_surface_actor = META_SURFACE_ACTOR (child_actor); + n_mapped_surfaces++; + } + + if (!topmost_surface_actor) { meta_topic (META_DEBUG_RENDER, "No surface-actor for window-actor"); return FALSE; } - topmost_surface_actor = META_SURFACE_ACTOR (child_actor); - window = meta_window_actor_get_meta_window (actor); if (!meta_surface_actor_is_opaque (topmost_surface_actor) && - !(meta_window_is_fullscreen (window) && - clutter_actor_get_n_children (surface_container) == 1)) + !(meta_window_is_fullscreen (window) && n_mapped_surfaces == 1)) { meta_topic (META_DEBUG_RENDER, "Window-actor is not opaque");