diff options
author | Robert Mader <robert.mader@posteo.de> | 2021-04-16 15:15:41 +0200 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2021-04-19 11:55:49 +0000 |
commit | f7768874e5ec2a808ccec424ed9e238e3dc13987 (patch) | |
tree | 3279683953a70fb1907e109ce3dbd2b25803a3a6 | |
parent | f4f82bcb96936fe108c0dd06936010ab5dee13ee (diff) | |
download | mutter-f7768874e5ec2a808ccec424ed9e238e3dc13987.tar.gz |
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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1831>
-rw-r--r-- | src/compositor/meta-window-actor-wayland.c | 65 |
1 files changed, 31 insertions, 34 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) -static gboolean -remove_surface_actor_from_children (GNode *node, - gpointer data) +typedef struct _SurfaceTreeTraverseData { - MetaWaylandSurface *surface = node->data; - MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); - MetaWindowActor *window_actor = data; - ClutterActor *parent; - - 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; -} + MetaWindowActor *window_actor; + int index; +} SurfaceTreeTraverseData; static gboolean -add_surface_actor_to_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; - - clutter_actor_add_child (CLUTTER_ACTOR (window_actor), - CLUTTER_ACTOR (surface_actor)); + SurfaceTreeTraverseData *traverse_data = data; + + 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 |