clutter/actor: Cancel delayed timelines on removal

Delayed clutter timelines might be removed while they are still in the
process of being executed, but if they are not playing yet their delay
timeout won't be stopped, causing them to be executed anyway, leading to a
potential crash.

In fact if something else keeps a reference on the timelines (i.e. gjs), the
dispose vfunc delay cancellation won't take effect, causing the timelines to
be started and added to the master clock.

To avoid this, expose clutter_timeline_cancel_delay() function and call it
if a timeline is not playing but has a delay set.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/815
https://gitlab.gnome.org/GNOME/mutter/merge_requests/805
This commit is contained in:
Marco Trevisan (Treviño) 2019-09-20 16:21:00 +02:00
parent 1e637bd7e1
commit c9c53cb55f
3 changed files with 5 additions and 1 deletions

View File

@ -19484,6 +19484,8 @@ transition_closure_free (gpointer data)
if (clutter_timeline_is_playing (timeline))
clutter_timeline_stop (timeline);
else if (clutter_timeline_get_delay (timeline) > 0)
clutter_timeline_cancel_delay (timeline);
/* remove the reference added in add_transition_internal() */
g_object_unref (clos->transition);

View File

@ -315,6 +315,8 @@ gboolean _clutter_run_progress_function (GType gtype,
gdouble progress,
GValue *retval);
void clutter_timeline_cancel_delay (ClutterTimeline *timeline);
G_END_DECLS
#endif /* __CLUTTER_PRIVATE_H__ */

View File

@ -424,7 +424,7 @@ clutter_timeline_set_custom_property (ClutterScriptable *scriptable,
g_object_set_property (G_OBJECT (scriptable), name, value);
}
static void
void
clutter_timeline_cancel_delay (ClutterTimeline *timeline)
{
g_clear_handle_id (&timeline->priv->delay_id, g_source_remove);