compositor: Unmap views moved to layers outside of the scene graph

commit 5fe02dc68e partially resolved the issue in #937 by bringing back
the old band-aid solution for layer moves. However, since the events of
commit bf228370ff and following commits we have a problem with
subsurfaces leaving garbage behind when minimized - see #366 which was
probably fixed for a while then became broken again.

When we minimize a view that has subsurfaces, by moving it to a layer
outside of the scene graph, we need to be sure to handle the subsurface
views - which follow their parent's layer instead of having
weston_view_move_to_layer() explicitly called.

Do this by assuming layers with an empty link are not part of the scene
graph and unmapping views when they're moved to these layers. This will
recursively unmap the subsurface views.

We can now remove the band-aid paint node destroy, as the unmap process
will destroy paint nodes as appropriate.

Fixes 5fe02dc68e

Fixes #937

Fixes #366

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2024-08-07 09:07:43 -05:00
parent 30fd16dae7
commit 003e529d46
1 changed files with 17 additions and 13 deletions

View File

@ -4148,6 +4148,15 @@ weston_view_set_alpha(struct weston_view *view, float alpha)
weston_view_update_transform(view);
}
static bool
layer_is_visible(struct weston_layer_entry *layer_entry)
{
if (wl_list_empty(&layer_entry->layer->link))
return false;
return true;
}
/** Move a weston_view to a layer
*
* This moves a view to a given point within a layer, identified by a
@ -4161,6 +4170,7 @@ weston_view_move_to_layer(struct weston_view *view,
struct weston_layer_entry *layer)
{
bool was_mapped = view->is_mapped;
bool visible = layer && layer_is_visible(layer);
if (layer == &view->layer_link)
return;
@ -4168,32 +4178,26 @@ weston_view_move_to_layer(struct weston_view *view,
view->surface->compositor->view_list_needs_rebuild = true;
/* Damage the view's old region, and remove it from the layer. */
if (weston_view_is_mapped(view)) {
/* Remove all paint nodes because we have no idea what a layer
* change does to view visibility on any output.
*
* For example, minimizing a window might move the view to a
* layer that's not part of the scene graph, and we'll no
* longer see that node in the paint node update loop, so
* won't know to damage its previously visible region.
*/
weston_view_destroy_paint_nodes(view);
if (weston_view_is_mapped(view))
weston_view_geometry_dirty_internal(view);
}
wl_list_remove(&view->layer_link.link);
wl_list_init(&view->layer_link.link);
view->layer_link.layer = NULL;
if (!layer) {
if (!visible)
weston_view_unmap(view);
if (!layer)
return;
}
/* Add the view to the new layer and damage its new region. */
wl_list_insert(&layer->link, &view->layer_link.link);
view->layer_link.layer = layer->layer;
if (!visible)
return;
view->is_mapped = true;
weston_view_geometry_dirty_internal(view);
weston_view_update_transform(view);