summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mader <robert.mader@posteo.de>2021-04-16 15:15:41 +0200
committerMarge Bot <marge-bot@gnome.org>2021-04-19 11:55:49 +0000
commitf7768874e5ec2a808ccec424ed9e238e3dc13987 (patch)
tree3279683953a70fb1907e109ce3dbd2b25803a3a6
parentf4f82bcb96936fe108c0dd06936010ab5dee13ee (diff)
downloadmutter-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.c65
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