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>
This commit is contained in:
Robert Mader 2021-04-16 15:15:41 +02:00 committed by Marge Bot
parent f4f82bcb96
commit f7768874e5

View File

@ -32,37 +32,36 @@ struct _MetaWindowActorWayland
G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR) G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR)
typedef struct _SurfaceTreeTraverseData
{
MetaWindowActor *window_actor;
int index;
} SurfaceTreeTraverseData;
static gboolean static gboolean
remove_surface_actor_from_children (GNode *node, set_surface_actor_index (GNode *node,
gpointer data) gpointer data)
{ {
MetaWaylandSurface *surface = node->data; MetaWaylandSurface *surface = node->data;
MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface);
MetaWindowActor *window_actor = data; SurfaceTreeTraverseData *traverse_data = data;
ClutterActor *parent;
parent = clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor)); if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor),
if (!parent) CLUTTER_ACTOR (surface_actor)))
return FALSE; {
clutter_actor_set_child_at_index (
g_return_val_if_fail (parent == CLUTTER_ACTOR (window_actor), FALSE); CLUTTER_ACTOR (traverse_data->window_actor),
CLUTTER_ACTOR (surface_actor),
clutter_actor_remove_child (CLUTTER_ACTOR (window_actor), traverse_data->index);
CLUTTER_ACTOR (surface_actor));
return FALSE;
} }
else
static gboolean
add_surface_actor_to_children (GNode *node,
gpointer data)
{ {
MetaWaylandSurface *surface = node->data; clutter_actor_insert_child_at_index (
MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); CLUTTER_ACTOR (traverse_data->window_actor),
MetaWindowActor *window_actor = data; CLUTTER_ACTOR (surface_actor),
traverse_data->index);
clutter_actor_add_child (CLUTTER_ACTOR (window_actor), }
CLUTTER_ACTOR (surface_actor)); traverse_data->index++;
return FALSE; return FALSE;
} }
@ -75,20 +74,18 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface ( MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
META_SURFACE_ACTOR_WAYLAND (surface_actor)); META_SURFACE_ACTOR_WAYLAND (surface_actor));
GNode *root_node = surface->subsurface_branch_node; GNode *root_node = surface->subsurface_branch_node;
SurfaceTreeTraverseData traverse_data;
traverse_data = (SurfaceTreeTraverseData) {
.window_actor = actor,
.index = 0,
};
g_node_traverse (root_node, g_node_traverse (root_node,
G_IN_ORDER, G_IN_ORDER,
G_TRAVERSE_LEAVES, G_TRAVERSE_LEAVES,
-1, -1,
remove_surface_actor_from_children, set_surface_actor_index,
actor); &traverse_data);
g_node_traverse (root_node,
G_IN_ORDER,
G_TRAVERSE_LEAVES,
-1,
add_surface_actor_to_children,
actor);
} }
static void static void