From 6ac54641c66efaa3725c72fb738e5fb1d4430010 Mon Sep 17 00:00:00 2001 From: Jonathan Matthew Date: Mon, 5 Jan 2009 20:26:47 +1000 Subject: [PATCH] Defer hiding windows until effects finish Add 'hide_after_effect' flag to MutterWindowPrivate, tracking whether the window needs to be hidden after all outstanding effects finish. Set or clear the flag as appropriate in clutter_cmp_set_window_hidden. In mutter_window_effect_completed, if hide_after_effect is TRUE and no other effects are in progress, hide the window. --- src/compositor/mutter/compositor-mutter.c | 79 +++++++++++++++-------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/src/compositor/mutter/compositor-mutter.c b/src/compositor/mutter/compositor-mutter.c index 8efc7af6b..12eb85419 100644 --- a/src/compositor/mutter/compositor-mutter.c +++ b/src/compositor/mutter/compositor-mutter.c @@ -196,6 +196,7 @@ struct _MutterWindowPrivate guint argb32 : 1; guint disposed : 1; guint is_minimized : 1; + guint hide_after_effect : 1; /* Desktop switching flags */ guint needs_map : 1; @@ -791,6 +792,16 @@ mutter_finish_workspace_switch (MetaCompScreen *info) } +static gboolean +effect_in_progress (MutterWindow *cw, gboolean include_destroy) +{ + return (cw->priv->minimize_in_progress || + cw->priv->maximize_in_progress || + cw->priv->unmaximize_in_progress || + cw->priv->map_in_progress || + (include_destroy && cw->priv->destroy_in_progress)); +} + void mutter_window_effect_completed (MutterWindow *cw, gulong event) { @@ -798,6 +809,7 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) MetaScreen *screen = priv->screen; MetaCompScreen *info = meta_screen_get_compositor_data (screen); ClutterActor *actor = CLUTTER_ACTOR (cw); + gboolean effect_done = FALSE; /* NB: Keep in mind that when effects get completed it possible * that the corresponding MetaWindow may have be been destroyed. @@ -832,6 +844,8 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) * made visible for sake of live previews. */ clutter_actor_show (a); + + effect_done = TRUE; } } break; @@ -856,6 +870,7 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) clutter_actor_set_anchor_point (actor, 0, 0); clutter_actor_set_position (actor, rect.x, rect.y); clutter_actor_show_all (actor); + effect_done = TRUE; } break; case MUTTER_PLUGIN_DESTROY: @@ -868,7 +883,10 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) } if (!priv->destroy_in_progress) - priv->needs_destroy = TRUE; + { + priv->needs_destroy = TRUE; + effect_done = TRUE; + } break; case MUTTER_PLUGIN_UNMAXIMIZE: priv->unmaximize_in_progress--; @@ -885,6 +903,7 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) clutter_actor_set_position (actor, rect.x, rect.y); mutter_window_detach (cw); repair_win (cw); + effect_done = TRUE; } break; case MUTTER_PLUGIN_MAXIMIZE: @@ -902,6 +921,7 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) clutter_actor_set_position (actor, rect.x, rect.y); mutter_window_detach (cw); repair_win (cw); + effect_done = TRUE; } break; case MUTTER_PLUGIN_SWITCH_WORKSPACE: @@ -927,23 +947,25 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event) case MUTTER_PLUGIN_DESTROY: case MUTTER_PLUGIN_UNMAXIMIZE: case MUTTER_PLUGIN_MAXIMIZE: - if (priv->needs_destroy) + + if (effect_done && + priv->hide_after_effect && + effect_in_progress (cw, TRUE) == FALSE) { - if (priv->minimize_in_progress || - priv->maximize_in_progress || - priv->unmaximize_in_progress || - priv->map_in_progress || - priv->destroy_in_progress) + if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group) { - /* wait until last effect finished */ - break; - } - else - { - clutter_actor_destroy (CLUTTER_ACTOR (cw)); - return; + clutter_actor_reparent (CLUTTER_ACTOR (cw), + info->hidden_group); } + priv->hide_after_effect = FALSE; } + + if (priv->needs_destroy && effect_in_progress (cw, TRUE) == FALSE) + { + clutter_actor_destroy (CLUTTER_ACTOR (cw)); + return; + } + default: break; } @@ -1025,10 +1047,7 @@ destroy_win (MutterWindow *cw) { priv->destroy_in_progress--; - if (priv->minimize_in_progress || - priv->maximize_in_progress || - priv->unmaximize_in_progress || - priv->map_in_progress) + if (effect_in_progress (cw, FALSE)) { priv->needs_destroy = TRUE; } @@ -1055,10 +1074,7 @@ sync_actor_position (MutterWindow *cw) priv->attrs.x = window_rect.x; priv->attrs.y = window_rect.y; - if (priv->maximize_in_progress || - priv->unmaximize_in_progress || - priv->minimize_in_progress || - priv->map_in_progress) + if (effect_in_progress (cw, FALSE)) return; clutter_actor_set_position (CLUTTER_ACTOR (cw), @@ -2192,6 +2208,7 @@ clutter_cmp_set_window_hidden (MetaCompositor *compositor, gboolean hidden) { MutterWindow *cw = MUTTER_WINDOW (meta_window_get_compositor_private (window)); + MutterWindowPrivate *priv = cw->priv; MetaCompScreen *info = meta_screen_get_compositor_data (screen); DEBUG_TRACE ("clutter_cmp_set_window_hidden\n"); @@ -2200,14 +2217,22 @@ clutter_cmp_set_window_hidden (MetaCompositor *compositor, if (hidden) { - /* FIXME: There needs to be a way to queue this if there is an effect - * in progress for this window */ - if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group) - clutter_actor_reparent (CLUTTER_ACTOR (cw), - info->hidden_group); + if (effect_in_progress (cw, TRUE)) + { + priv->hide_after_effect = TRUE; + } + else + { + if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group) + { + clutter_actor_reparent (CLUTTER_ACTOR (cw), + info->hidden_group); + } + } } else { + priv->hide_after_effect = FALSE; if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->window_group) clutter_actor_reparent (CLUTTER_ACTOR (cw), info->window_group);