From da633dcc52768383497f5616bfb7eb7dddc12f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 1 Jul 2020 00:14:46 +0200 Subject: [PATCH] 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 --- clutter/clutter/clutter-actor.c | 7 ++--- src/tests/stage-view-tests.c | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index 7d3738ada..1a622c8d2 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -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; diff --git a/src/tests/stage-view-tests.c b/src/tests/stage-view-tests.c index 9c31353e0..76da1db45 100644 --- a/src/tests/stage-view-tests.c +++ b/src/tests/stage-view-tests.c @@ -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",