From 7e5366f2336d39ad5699bc9dbff9e8b3c30bf01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 8 Nov 2019 22:41:35 +0100 Subject: [PATCH] plugins/default: Handle skipped animations We currently assume that the actor_animate() helper function returns a timeline. However Clutter may skip implicit animations and simple set properties directly, for example when the actor is hidden. The returned timeline will be NULL in that case, and we abort when using it as instance parameter to g_signal_connect(). Fix this by only setting up a completed handler when we are actually animating, and complete the effect directly otherwise. https://gitlab.gnome.org/GNOME/mutter/merge_requests/925 --- src/compositor/plugins/default.c | 43 ++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index 378009006..08ecf01ac 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -590,6 +590,7 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) MetaWindowType type; MetaRectangle icon_geometry; MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); + ClutterTimeline *timeline = NULL; ClutterActor *actor = CLUTTER_ACTOR (window_actor); @@ -602,24 +603,28 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) } if (type == META_WINDOW_NORMAL) + { + timeline = actor_animate (actor, + CLUTTER_EASE_IN_SINE, + MINIMIZE_TIMEOUT, + "scale-x", 0.0, + "scale-y", 0.0, + "x", (double)icon_geometry.x, + "y", (double)icon_geometry.y, + NULL); + } + + if (timeline) { EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - apriv->tml_minimize = actor_animate (actor, - CLUTTER_EASE_IN_SINE, - MINIMIZE_TIMEOUT, - "scale-x", 0.0, - "scale-y", 0.0, - "x", (double)icon_geometry.x, - "y", (double)icon_geometry.y, - NULL); + apriv->tml_minimize = timeline; data->plugin = plugin; data->actor = actor; g_signal_connect (apriv->tml_minimize, "completed", G_CALLBACK (on_minimize_effect_complete), data); - } else meta_plugin_minimize_completed (plugin, window_actor); @@ -708,21 +713,27 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) MetaWindowType type; ClutterActor *actor = CLUTTER_ACTOR (window_actor); MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); + ClutterTimeline *timeline = NULL; type = meta_window_get_window_type (meta_window); if (type == META_WINDOW_NORMAL) + { + timeline = actor_animate (actor, + CLUTTER_EASE_OUT_QUAD, + DESTROY_TIMEOUT, + "opacity", 0, + "scale-x", 0.8, + "scale-y", 0.8, + NULL); + } + + if (timeline) { EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - apriv->tml_destroy = actor_animate (actor, - CLUTTER_EASE_OUT_QUAD, - DESTROY_TIMEOUT, - "opacity", 0, - "scale-x", 0.8, - "scale-y", 0.8, - NULL); + apriv->tml_destroy = timeline; data->plugin = plugin; data->actor = actor; g_signal_connect (apriv->tml_destroy, "completed",