[mutter] clutter/stage: Don't assume stage relayouts reallocate everything



commit e74c2e42cf3dc744aaa53cb5a683138425cda9b6
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Fri Apr 3 10:40:46 2020 +0200

    clutter/stage: Don't assume stage relayouts reallocate everything
    
    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 and still add new entries to the hashtable if a stage
    relayout is already queued 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 https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1173

 clutter/clutter/clutter-stage.c | 6 ------
 1 file changed, 6 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index fc037662c..e1e3e6e77 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -1310,15 +1310,9 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
 {
   ClutterStagePrivate *priv = stage->priv;
 
-  if (g_hash_table_contains (priv->pending_relayouts, stage))
-    return;
-
   if (g_hash_table_size (priv->pending_relayouts) == 0)
     _clutter_stage_schedule_update (stage);
 
-  if (actor == (ClutterActor *) stage)
-    g_hash_table_remove_all (priv->pending_relayouts);
-
   g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
   priv->pending_relayouts_version++;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]