clutter/actor: Notify hidden actors about absolute allocation changes

With commit 0eab73dc2e we introduced an optimization of not doing
allocations for actors which are hidden. This broke the propagation of
absolute origin changes to hidden actors, so if an actor is moved while
its child is hidden, the child will not get
priv->needs_compute_resource_scale set to TRUE, which means the resource
scale won't be updated when the child gets mapped and shown again.

Since we now have priv->absolute_origin_changed, we can simply check
whether that is TRUE for our parent before bailing out of
clutter_actor_allocate() and if it is, notify the whole hidden sub-tree
about the absolute origin change.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1247
This commit is contained in:
Jonas Dreßler 2020-05-10 11:26:37 +02:00 committed by Jonas Ådahl
parent 38104755a2
commit 9b39e37fee

View File

@ -2560,6 +2560,22 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
g_object_thaw_notify (obj); g_object_thaw_notify (obj);
} }
static void
absolute_allocation_changed (ClutterActor *actor)
{
actor->priv->needs_compute_resource_scale = TRUE;
}
static ClutterActorTraverseVisitFlags
absolute_allocation_changed_cb (ClutterActor *actor,
int depth,
gpointer user_data)
{
absolute_allocation_changed (actor);
return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
}
/*< private > /*< private >
* clutter_actor_set_allocation_internal: * clutter_actor_set_allocation_internal:
* @self: a #ClutterActor * @self: a #ClutterActor
@ -2606,7 +2622,7 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
priv->absolute_origin_changed |= x1_changed || y1_changed; priv->absolute_origin_changed |= x1_changed || y1_changed;
if (priv->absolute_origin_changed || x2_changed || y2_changed) if (priv->absolute_origin_changed || x2_changed || y2_changed)
priv->needs_compute_resource_scale = TRUE; absolute_allocation_changed (self);
if (x1_changed || if (x1_changed ||
y1_changed || y1_changed ||
@ -10111,11 +10127,26 @@ clutter_actor_allocate (ClutterActor *self,
return; return;
} }
if (!clutter_actor_is_visible (self))
return;
priv = self->priv; priv = self->priv;
priv->absolute_origin_changed = priv->parent
? priv->parent->priv->absolute_origin_changed
: FALSE;
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
{
if (priv->absolute_origin_changed)
{
_clutter_actor_traverse (self,
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
absolute_allocation_changed_cb,
NULL,
NULL);
}
goto out;
}
old_allocation = priv->allocation; old_allocation = priv->allocation;
real_allocation = *box; real_allocation = *box;
@ -10147,10 +10178,6 @@ clutter_actor_allocate (ClutterActor *self,
size_changed = (real_allocation.x2 != old_allocation.x2 || size_changed = (real_allocation.x2 != old_allocation.x2 ||
real_allocation.y2 != old_allocation.y2); real_allocation.y2 != old_allocation.y2);
priv->absolute_origin_changed = priv->parent
? priv->parent->priv->absolute_origin_changed
: FALSE;
stage_allocation_changed = stage_allocation_changed =
priv->absolute_origin_changed || origin_changed || size_changed; priv->absolute_origin_changed || origin_changed || size_changed;