Skip to content

clutter/actor: Remove actors from shallow relayout list when unrealizing

Jonas Dreßler requested to merge verdre/mutter:fix-more-fallout into master

With the introduction of the shallow relayout mechanism another small but severe regression sneaked into our layout machinery: We might allocate an actor twice during the same allocation cycle, with one allocation happening using the wrong parent.

This issue happens when reparenting an actor from a NO_LAYOUT parent to a non-NO_LAYOUT parent, in particular it triggered a bug in gnome-shell when DND reparents a child from the NO_LAYOUT uiGroup to the overviews Workspace actor after a drag ended. The reason the issue happens is the following chain of events:

  1. child of a NO_LAYOUT parent queues a relayout, this child is added to the priv->pending_relayouts list maintained by ClutterStage

  2. child is reparented to a different parent which doesn't have the NO_LAYOUT flag set, another relayout is queued, this time a different actor is added to the priv->pending_relayouts list

  3. the relayout happens and we go through the pending_relayouts list backwards, that means the correct relayout queued during 2. happens first, then the old one happens and we simply call clutter_actor_allocate_preferred_size() on the actor, that allocation overrides the other, correct one.

So fix that issue by adding a method to ClutterStage which removes actors from the pending_relayouts list again and call this method as soon as an actor is detached from the stage.

With that in place, we can also remove the check whether an actor is still on stage while looping through pending_relayouts. In case something else is going wrong and the actor is not on stage, clutter_actor_allocate() will warn anyway.

Merge request reports