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:
parent
f4f82bcb96
commit
f7768874e5
1 changed files with 32 additions and 35 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue