From 06c4841e2286ed7f03e5227d158fb38e712e7437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 12 Aug 2020 19:27:47 +0200 Subject: [PATCH] clutter/timeline: Listen to 'stage-view-changed' on picked actor When we pick the frame clock given the associated actor, that frame clock in fact comes from a picked actor. In order to not end up with stale frame clocks, which may happen on e.g. hotplugs, monitor layout changes, or non-optimal frame clocks, which may happen when the parent used for picking the clock moves to another view, lets listen to 'stage-views-changed' on the actor used for picking the clock too. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1327 https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1404 --- clutter/clutter/clutter-timeline.c | 32 +++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/clutter/clutter/clutter-timeline.c b/clutter/clutter/clutter-timeline.c index 4a36da435..23392fc99 100644 --- a/clutter/clutter/clutter-timeline.c +++ b/clutter/clutter/clutter-timeline.c @@ -114,6 +114,8 @@ struct _ClutterTimelinePrivate ClutterFrameClock *custom_frame_clock; ClutterFrameClock *frame_clock; + ClutterActor *frame_clock_actor; + gulong frame_clock_actor_stage_views_handler_id; ClutterActor *actor; gulong actor_destroy_handler_id; @@ -383,19 +385,40 @@ on_stage_stage_views_changed (ClutterActor *stage, update_frame_clock (timeline); } +static void +on_frame_clock_actor_stage_views_changed (ClutterActor *frame_clock_actor, + ClutterTimeline *timeline) +{ + update_frame_clock (timeline); +} + static void update_frame_clock (ClutterTimeline *timeline) { ClutterTimelinePrivate *priv = timeline->priv; ClutterFrameClock *frame_clock = NULL; ClutterActor *stage; + ClutterActor *frame_clock_actor; if (!priv->actor) goto out; - frame_clock = clutter_actor_pick_frame_clock (priv->actor, NULL); + if (priv->frame_clock_actor) + { + g_clear_signal_handler (&priv->frame_clock_actor_stage_views_handler_id, + priv->frame_clock_actor); + g_clear_weak_pointer (&priv->frame_clock_actor); + } + + frame_clock = clutter_actor_pick_frame_clock (priv->actor, &frame_clock_actor); if (frame_clock) { + g_set_weak_pointer (&priv->frame_clock_actor, frame_clock_actor); + priv->frame_clock_actor_stage_views_handler_id = + g_signal_connect (frame_clock_actor, "stage-views-changed", + G_CALLBACK (on_frame_clock_actor_stage_views_changed), + timeline); + g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage); goto out; } @@ -737,6 +760,13 @@ clutter_timeline_dispose (GObject *object) priv->actor = NULL; } + if (priv->frame_clock_actor) + { + g_clear_signal_handler (&priv->frame_clock_actor_stage_views_handler_id, + priv->frame_clock_actor); + g_clear_weak_pointer (&priv->frame_clock_actor); + } + if (priv->progress_notify != NULL) { priv->progress_notify (priv->progress_data);