From a8975428763a0328c8ae563d821572a43f821050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 24 Nov 2022 16:18:04 +0100 Subject: [PATCH] clutter/actor: Stop transitions in children when removing When we remove a child, we stop its transitions (animations), but we didn't stop animations on grand children. What we did, however, was to clear the stage views of the grand children, and this caused a bunch of orphaned transitions (ClutterTimeline) and accompanied warnings. Make it so that if we stop transitions, and clear stage views, also stop transitions for the grand children. Detached children don't have a way to continue animating anyway, since they have no stage view (thus frame clock) to be driven by. Part-of: --- clutter/clutter/clutter-actor-private.h | 3 ++- clutter/clutter/clutter-actor.c | 11 ++++++++--- clutter/clutter/clutter-stage.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/clutter/clutter/clutter-actor-private.h b/clutter/clutter/clutter-actor-private.h index 764705447..0dd038564 100644 --- a/clutter/clutter/clutter-actor-private.h +++ b/clutter/clutter/clutter-actor-private.h @@ -255,7 +255,8 @@ void _clutter_actor_attach_clone void _clutter_actor_detach_clone (ClutterActor *actor, ClutterActor *clone); void _clutter_actor_queue_only_relayout (ClutterActor *actor); -void clutter_actor_clear_stage_views_recursive (ClutterActor *actor); +void clutter_actor_clear_stage_views_recursive (ClutterActor *actor, + gboolean stop_transitions); float clutter_actor_get_real_resource_scale (ClutterActor *actor); diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index dd968585f..6ed14e29e 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -4200,7 +4200,7 @@ clutter_actor_remove_child_internal (ClutterActor *self, * cleared as the child and its children leave the actor tree. */ if (clear_stage_views && !CLUTTER_ACTOR_IN_DESTRUCTION (child)) - clutter_actor_clear_stage_views_recursive (child); + clutter_actor_clear_stage_views_recursive (child, stop_transitions); if (emit_parent_set && !CLUTTER_ACTOR_IN_DESTRUCTION (child)) g_signal_emit (child, actor_signals[PARENT_SET], 0, self); @@ -15291,8 +15291,12 @@ clear_stage_views_cb (ClutterActor *actor, int depth, gpointer user_data) { + gboolean stop_transitions = GPOINTER_TO_INT (user_data); g_autoptr (GList) old_stage_views = NULL; + if (stop_transitions) + _clutter_actor_stop_transitions (actor); + actor->priv->needs_update_stage_views = TRUE; old_stage_views = g_steal_pointer (&actor->priv->stage_views); @@ -15318,13 +15322,14 @@ maybe_emit_stage_views_changed_cb (ClutterActor *actor, } void -clutter_actor_clear_stage_views_recursive (ClutterActor *self) +clutter_actor_clear_stage_views_recursive (ClutterActor *self, + gboolean stop_transitions) { _clutter_actor_traverse (self, CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, clear_stage_views_cb, NULL, - NULL); + GINT_TO_POINTER (stop_transitions)); _clutter_actor_traverse (self, CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, maybe_emit_stage_views_changed_cb, diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index f32b2621e..f5d4517a4 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -3097,7 +3097,7 @@ clutter_stage_peek_stage_views (ClutterStage *stage) void clutter_stage_clear_stage_views (ClutterStage *stage) { - clutter_actor_clear_stage_views_recursive (CLUTTER_ACTOR (stage)); + clutter_actor_clear_stage_views_recursive (CLUTTER_ACTOR (stage), FALSE); } GList *