Skip to content

clutter/stage: Don't flush relayout hashtable on stage relayouts

Jonas Dreßler requested to merge verdre/mutter:fix-blur-effect-crash into master

With the introduction of "shallow" relayouts, we are now able to enter allocation cycles not only at the stage but also deeper down the hierarchy if we know an actors allocation isn't affected by its children since the NO_LAYOUT flag is set.

Now that means when queuing relayouts it's possible that priv->needs_allocation gets set to TRUE for some actors down the hierarchy, but not for actors higher up in the hierarchy. An actor tree where that happens could look like that:

stage -> container -> container2 (NO_LAYOUT) -> textActor

With that tree, if the "textActor" queues a relayout, "container2" will be added to the relayout hashtable of the stage and the actors "stage" and "container" will have priv->needs_allocation set to FALSE.

Now if another relayout on the stage actor is queued, clutter_stage_queue_actor_relayout() currently removes all the other hashtable entries in favour of the stage entry, (wrongly) assuming that will allocate everything. It doesn't allocate everything because in the example above "container" has priv->needs_allocation set to FALSE, which makes clutter_actor_allocate() return early before allocating its children, so in the end "container2" will never get a new allocation.

To fix this, stop flushing the relayout hashtable when queuing a stage-relayout to make sure we still go through all the previously queued "shallow" relayouts. That shouldn't hurt performance, too, because as soon as an actor got allocated once, it doesn't need an allocation anymore and should bail out in clutter_actor_allocate() as long as it's absolute position didn't change.

Fixes gnome-shell#2538 (closed)

Merge request reports