Skip to content

Commit 0da883b

Browse files
committed
wayland/subsurface: Move actor unparenting back to rebuild_surface_tree()
Unparenting the surface actor when the subsurface object is destroyed has several issues: subsurface actors can be unparented while a close animation is still ongoing, breaking the animation for e.g. Firefox. adding and removing the actor to/from the parent is not handled in one place, making the code harder to follow. if the destroyed subsurface had children of its own, they potentially stick around until a surface-tree rebuild. This makes the Firefox hamburger menu not close with the "compositor" backend. Move the unparenting back to meta_window_actor_wayland_rebuild_surface_tree() and instead just notify the parent of a state change, if it still exist. This will ensure a correct mapping between the subsurface node tree and the flat surface actor list. In case of the closing animation the parent will already be removed and the call is skipped.
1 parent f378f68 commit 0da883b

File tree

2 files changed

+48
-28
lines changed

2 files changed

+48
-28
lines changed

src/compositor/meta-window-actor-wayland.c

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,43 @@ typedef struct _SurfaceTreeTraverseData
3939
} SurfaceTreeTraverseData;
4040

4141
static gboolean
42-
set_surface_actor_index (GNode *node,
43-
gpointer data)
42+
get_surface_actor_list (GNode *node,
43+
gpointer data)
4444
{
4545
MetaWaylandSurface *surface = node->data;
4646
MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface);
47+
GList **surface_actors = data;
48+
49+
*surface_actors = g_list_prepend (*surface_actors, surface_actor);
50+
return FALSE;
51+
}
4752

53+
static gboolean
54+
set_surface_actor_index (GNode *node,
55+
gpointer data)
56+
{
57+
MetaWaylandSurface *surface = node->data;
4858
SurfaceTreeTraverseData *traverse_data = data;
4959

50-
if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor),
51-
CLUTTER_ACTOR (surface_actor)))
60+
ClutterActor *window_actor = CLUTTER_ACTOR (traverse_data->window_actor);
61+
ClutterActor *surface_actor =
62+
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
63+
64+
if (clutter_actor_contains (window_actor, surface_actor))
5265
{
53-
clutter_actor_set_child_at_index (
54-
CLUTTER_ACTOR (traverse_data->window_actor),
55-
CLUTTER_ACTOR (surface_actor),
56-
traverse_data->index);
66+
if (clutter_actor_get_child_at_index (window_actor, traverse_data->index) !=
67+
surface_actor)
68+
{
69+
clutter_actor_set_child_at_index (window_actor,
70+
surface_actor,
71+
traverse_data->index);
72+
}
5773
}
5874
else
5975
{
60-
clutter_actor_insert_child_at_index (
61-
CLUTTER_ACTOR (traverse_data->window_actor),
62-
CLUTTER_ACTOR (surface_actor),
63-
traverse_data->index);
76+
clutter_actor_insert_child_at_index (window_actor,
77+
surface_actor,
78+
traverse_data->index);
6479
}
6580
traverse_data->index++;
6681

@@ -75,8 +90,28 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
7590
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
7691
META_SURFACE_ACTOR_WAYLAND (surface_actor));
7792
GNode *root_node = surface->subsurface_branch_node;
93+
g_autoptr (GList) surface_actors = NULL;
94+
g_autoptr (GList) children = NULL;
95+
GList *l;
7896
SurfaceTreeTraverseData traverse_data;
7997

98+
g_node_traverse (root_node,
99+
G_IN_ORDER,
100+
G_TRAVERSE_LEAVES,
101+
-1,
102+
get_surface_actor_list,
103+
&surface_actors);
104+
105+
children = clutter_actor_get_children (CLUTTER_ACTOR (actor));
106+
for (l = children; l; l = l->next)
107+
{
108+
ClutterActor *child_actor = l->data;
109+
110+
if (META_IS_SURFACE_ACTOR_WAYLAND (child_actor) &&
111+
!g_list_find (surface_actors, child_actor))
112+
clutter_actor_remove_child (CLUTTER_ACTOR (actor), child_actor);
113+
}
114+
80115
traverse_data = (SurfaceTreeTraverseData) {
81116
.window_actor = actor,
82117
.index = 0,

src/wayland/meta-wayland-subsurface.c

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -281,31 +281,16 @@ meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass)
281281
meta_wayland_subsurface_sync_actor_state;
282282
}
283283

284-
static void
285-
unparent_actor (MetaWaylandSurface *surface)
286-
{
287-
ClutterActor *actor;
288-
ClutterActor *parent_actor;
289-
290-
actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
291-
if (!actor)
292-
return;
293-
294-
parent_actor = clutter_actor_get_parent (actor);
295-
if (parent_actor)
296-
clutter_actor_remove_child (parent_actor, actor);
297-
}
298-
299284
static void
300285
wl_subsurface_destructor (struct wl_resource *resource)
301286
{
302287
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
303288

304289
g_node_unlink (surface->subsurface_branch_node);
305-
unparent_actor (surface);
306290

307291
if (surface->sub.parent)
308292
{
293+
meta_wayland_surface_notify_subsurface_state_changed (surface->sub.parent);
309294
wl_list_remove (&surface->sub.parent_destroy_listener.link);
310295
surface->sub.parent = NULL;
311296
}

0 commit comments

Comments
 (0)