[mutter] clutter/timeline: Listen to 'stage-view-changed' on picked actor



commit 06c4841e2286ed7f03e5227d158fb38e712e7437
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Aug 12 19:27:47 2020 +0200

    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 4a36da4352..23392fc99d 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]