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
This commit is contained in:
Florian Müllner 2019-11-08 22:41:35 +01:00 committed by Georges Basile Stavracas Neto
parent cf78598974
commit 7e5366f233

View File

@ -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);
@ -603,10 +604,7 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
if (type == META_WINDOW_NORMAL)
{
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
ActorPrivate *apriv = get_actor_private (window_actor);
apriv->tml_minimize = actor_animate (actor,
timeline = actor_animate (actor,
CLUTTER_EASE_IN_SINE,
MINIMIZE_TIMEOUT,
"scale-x", 0.0,
@ -614,12 +612,19 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
"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 = 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)
{
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
ActorPrivate *apriv = get_actor_private (window_actor);
apriv->tml_destroy = actor_animate (actor,
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 = timeline;
data->plugin = plugin;
data->actor = actor;
g_signal_connect (apriv->tml_destroy, "completed",