From f7768874e5ec2a808ccec424ed9e238e3dc13987 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Fri, 16 Apr 2021 15:15:41 +0200 Subject: [PATCH] window-actor/wayland: Cleaner subsurface reordering Currently when reordering subsurfaces, we un- and reparent all child actors of the window actor. This is unnecessarily wasteful and triggers bugs in clutter. While the underlying issue should be fixed eventually, simply reorder the actors with the tools clutter provides us with, avoiding those bugs and likely being faster as well. Part-of: --- src/compositor/meta-window-actor-wayland.c | 67 +++++++++++----------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/src/compositor/meta-window-actor-wayland.c b/src/compositor/meta-window-actor-wayland.c index 7c3be5690..b1fe61641 100644 --- a/src/compositor/meta-window-actor-wayland.c +++ b/src/compositor/meta-window-actor-wayland.c @@ -32,37 +32,36 @@ struct _MetaWindowActorWayland G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR) +typedef struct _SurfaceTreeTraverseData +{ + MetaWindowActor *window_actor; + int index; +} SurfaceTreeTraverseData; + static gboolean -remove_surface_actor_from_children (GNode *node, - gpointer data) +set_surface_actor_index (GNode *node, + gpointer data) { MetaWaylandSurface *surface = node->data; MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); - MetaWindowActor *window_actor = data; - ClutterActor *parent; + SurfaceTreeTraverseData *traverse_data = data; - parent = clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor)); - if (!parent) - return FALSE; - - g_return_val_if_fail (parent == CLUTTER_ACTOR (window_actor), FALSE); - - clutter_actor_remove_child (CLUTTER_ACTOR (window_actor), - CLUTTER_ACTOR (surface_actor)); - - return FALSE; -} - -static gboolean -add_surface_actor_to_children (GNode *node, - gpointer data) -{ - MetaWaylandSurface *surface = node->data; - MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); - MetaWindowActor *window_actor = data; - - clutter_actor_add_child (CLUTTER_ACTOR (window_actor), - CLUTTER_ACTOR (surface_actor)); + if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor), + CLUTTER_ACTOR (surface_actor))) + { + clutter_actor_set_child_at_index ( + CLUTTER_ACTOR (traverse_data->window_actor), + CLUTTER_ACTOR (surface_actor), + traverse_data->index); + } + else + { + clutter_actor_insert_child_at_index ( + CLUTTER_ACTOR (traverse_data->window_actor), + CLUTTER_ACTOR (surface_actor), + traverse_data->index); + } + traverse_data->index++; return FALSE; } @@ -75,20 +74,18 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor) MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface ( META_SURFACE_ACTOR_WAYLAND (surface_actor)); GNode *root_node = surface->subsurface_branch_node; + SurfaceTreeTraverseData traverse_data; + traverse_data = (SurfaceTreeTraverseData) { + .window_actor = actor, + .index = 0, + }; g_node_traverse (root_node, G_IN_ORDER, G_TRAVERSE_LEAVES, -1, - remove_surface_actor_from_children, - actor); - - g_node_traverse (root_node, - G_IN_ORDER, - G_TRAVERSE_LEAVES, - -1, - add_surface_actor_to_children, - actor); + set_surface_actor_index, + &traverse_data); } static void