clutter/actor: Make has_mapped_clones() factor in parent actors

All existing users of clutter_actor_has_mapped_clones() actually want to
know whether the actor is being cloned by a visible clone, it doesn't
matter to them if that clone is attached to an actor somewhere else in
the tree or to the actor itself.

So make clutter_actor_has_mapped_clones() a bit more convenient to use
and also check the clones of the parent-actors in that function.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1235
This commit is contained in:
Jonas Dreßler 2020-05-05 16:19:46 +02:00
parent e68bb27df2
commit 2791f5b466
2 changed files with 29 additions and 30 deletions

View File

@ -8847,25 +8847,21 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
return;
/* we can ignore unmapped actors, unless they have at least one
* mapped clone or they are inside a cloned branch of the scene
* graph, as unmapped actors will simply be left unpainted.
/* we can ignore unmapped actors, unless they are inside a cloned branch
* of the scene graph, as unmapped actors will simply be left unpainted.
*
* this allows us to ignore redraws queued on leaf nodes when one
* of their parents has been hidden
*/
if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
self->priv->in_cloned_branch == 0 &&
!clutter_actor_has_mapped_clones (self))
{
CLUTTER_NOTE (PAINT,
"Skipping queue_redraw('%s'): mapped=%s, "
"mapped_clones=%s, "
"in_cloned_branch=%s",
"has_mapped_clones=%s",
_clutter_actor_get_debug_name (self),
CLUTTER_ACTOR_IS_MAPPED (self) ? "yes" : "no",
clutter_actor_has_mapped_clones (self) ? "yes" : "no",
self->priv->in_cloned_branch != 0 ? "yes" : "no");
clutter_actor_has_mapped_clones (self) ? "yes" : "no");
return;
}
@ -19084,7 +19080,6 @@ should_skip_implicit_transition (ClutterActor *self,
* when those transitions happen
*/
if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
priv->in_cloned_branch == 0 &&
!clutter_actor_has_mapped_clones (self))
return TRUE;
@ -20704,32 +20699,42 @@ _clutter_actor_queue_relayout_on_clones (ClutterActor *self)
* clutter_actor_has_mapped_clones:
* @self: a #ClutterActor
*
* Returns whether a #ClutterActor has any mapped clones.
* Returns whether a #ClutterActor or any parent actors have mapped clones
* that are clone-painting @self.
*
* Return: %TRUE if the actor has mapped clones, and %FALSE otherwise
*
* Since: 1.16
* Returns: %TRUE if the actor has mapped clones, %FALSE otherwise
*/
gboolean
clutter_actor_has_mapped_clones (ClutterActor *self)
{
ClutterActorPrivate *priv;
ClutterActor *actor;
GHashTableIter iter;
gpointer key;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
priv = self->priv;
if (priv->clones == NULL)
if (self->priv->in_cloned_branch == 0)
return FALSE;
g_hash_table_iter_init (&iter, priv->clones);
for (actor = self; actor; actor = actor->priv->parent)
{
if (actor->priv->clones)
{
g_hash_table_iter_init (&iter, actor->priv->clones);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
if (CLUTTER_ACTOR_IS_MAPPED (key))
return TRUE;
}
}
/* Clones will force-show their own source actor but not children of
* it, so if we're hidden and an actor up the hierarchy has a clone,
* we won't be visisble.
*/
if (!CLUTTER_ACTOR_IS_VISIBLE (actor))
return FALSE;
}
return FALSE;
}

View File

@ -63,17 +63,11 @@ effective_unobscured_region (MetaSurfaceActor *surface_actor)
{
MetaSurfaceActorPrivate *priv =
meta_surface_actor_get_instance_private (surface_actor);
ClutterActor *actor;
ClutterActor *actor = CLUTTER_ACTOR (surface_actor);
/* Fail if we have any mapped clones. */
actor = CLUTTER_ACTOR (surface_actor);
do
{
if (clutter_actor_has_mapped_clones (actor))
return NULL;
actor = clutter_actor_get_parent (actor);
}
while (actor != NULL);
return priv->unobscured_region;
}