clutter/actor: Allocate with the same box if deferred due to transition

When a transition is created for the allocation change, it will delay
the new allocation box getting set depending on transition details.
This, however, means that e.g. the 'needs_allocation' flag never gets
cleared if a transition is created, causing other parts of the code to
get confused thinking it didn't pass through a layout step before paint.

Fix this by calling clutter_actor_allocate_internal() with the current
allocation box if a transition was created, so that we'll properly clear
'needs_allocation' flag.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1345
This commit is contained in:
Jonas Ådahl 2020-07-01 00:14:46 +02:00
parent 86646679f1
commit da633dcc52
2 changed files with 52 additions and 3 deletions

View File

@ -9599,9 +9599,10 @@ clutter_actor_allocate (ClutterActor *self,
goto out;
}
_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
&priv->allocation,
&real_allocation);
if (_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
&priv->allocation,
&real_allocation))
clutter_actor_allocate_internal (self, &priv->allocation);
out:
priv->absolute_origin_changed = FALSE;

View File

@ -250,6 +250,52 @@ meta_test_actor_stage_views (void)
clutter_actor_destroy (container);
}
static void
on_relayout_actor_frame (ClutterTimeline *timeline,
int msec,
ClutterActor *actor)
{
MetaBackend *backend = meta_get_backend ();
ClutterActor *stage = meta_backend_get_stage (backend);
clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
}
static void
meta_test_actor_stage_views_relayout (void)
{
MetaBackend *backend = meta_get_backend ();
ClutterActor *stage, *actor;
ClutterTransition *transition;
GMainLoop *main_loop;
stage = meta_backend_get_stage (backend);
actor = clutter_actor_new ();
clutter_actor_set_size (actor, 100, 100);
clutter_actor_set_easing_duration (actor, 100);
clutter_actor_add_child (stage, actor);
clutter_actor_show (stage);
wait_for_paint (stage);
clutter_actor_set_position (actor, 1000.0, 0.0);
transition = clutter_actor_get_transition (actor, "position");
g_signal_connect_after (transition, "new-frame",
G_CALLBACK (on_relayout_actor_frame),
actor);
main_loop = g_main_loop_new (NULL, FALSE);
g_signal_connect_swapped (transition, "stopped",
G_CALLBACK (g_main_loop_quit),
main_loop);
g_main_loop_run (main_loop);
clutter_actor_destroy (actor);
g_main_loop_unref (main_loop);
}
static void
meta_test_actor_stage_views_reparent (void)
{
@ -478,6 +524,8 @@ init_tests (int argc, char **argv)
meta_test_stage_views_exist);
g_test_add_func ("/stage-views/actor-stage-views",
meta_test_actor_stage_views);
g_test_add_func ("/stage-views/actor-stage-views-relayout",
meta_test_actor_stage_views_relayout);
g_test_add_func ("/stage-views/actor-stage-views-reparent",
meta_test_actor_stage_views_reparent);
g_test_add_func ("/stage-views/actor-stage-views-hide-parent",