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.
This commit is contained in:
Jonathan Matthew 2009-01-05 20:26:47 +10:00
parent 1d38209520
commit 6ac54641c6

View File

@ -196,6 +196,7 @@ struct _MutterWindowPrivate
guint argb32 : 1; guint argb32 : 1;
guint disposed : 1; guint disposed : 1;
guint is_minimized : 1; guint is_minimized : 1;
guint hide_after_effect : 1;
/* Desktop switching flags */ /* Desktop switching flags */
guint needs_map : 1; 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 void
mutter_window_effect_completed (MutterWindow *cw, gulong event) mutter_window_effect_completed (MutterWindow *cw, gulong event)
{ {
@ -798,6 +809,7 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event)
MetaScreen *screen = priv->screen; MetaScreen *screen = priv->screen;
MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaCompScreen *info = meta_screen_get_compositor_data (screen);
ClutterActor *actor = CLUTTER_ACTOR (cw); ClutterActor *actor = CLUTTER_ACTOR (cw);
gboolean effect_done = FALSE;
/* NB: Keep in mind that when effects get completed it possible /* NB: Keep in mind that when effects get completed it possible
* that the corresponding MetaWindow may have be been destroyed. * 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. * made visible for sake of live previews.
*/ */
clutter_actor_show (a); clutter_actor_show (a);
effect_done = TRUE;
} }
} }
break; break;
@ -856,6 +870,7 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event)
clutter_actor_set_anchor_point (actor, 0, 0); clutter_actor_set_anchor_point (actor, 0, 0);
clutter_actor_set_position (actor, rect.x, rect.y); clutter_actor_set_position (actor, rect.x, rect.y);
clutter_actor_show_all (actor); clutter_actor_show_all (actor);
effect_done = TRUE;
} }
break; break;
case MUTTER_PLUGIN_DESTROY: case MUTTER_PLUGIN_DESTROY:
@ -868,7 +883,10 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event)
} }
if (!priv->destroy_in_progress) if (!priv->destroy_in_progress)
priv->needs_destroy = TRUE; {
priv->needs_destroy = TRUE;
effect_done = TRUE;
}
break; break;
case MUTTER_PLUGIN_UNMAXIMIZE: case MUTTER_PLUGIN_UNMAXIMIZE:
priv->unmaximize_in_progress--; 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); clutter_actor_set_position (actor, rect.x, rect.y);
mutter_window_detach (cw); mutter_window_detach (cw);
repair_win (cw); repair_win (cw);
effect_done = TRUE;
} }
break; break;
case MUTTER_PLUGIN_MAXIMIZE: 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); clutter_actor_set_position (actor, rect.x, rect.y);
mutter_window_detach (cw); mutter_window_detach (cw);
repair_win (cw); repair_win (cw);
effect_done = TRUE;
} }
break; break;
case MUTTER_PLUGIN_SWITCH_WORKSPACE: case MUTTER_PLUGIN_SWITCH_WORKSPACE:
@ -927,23 +947,25 @@ mutter_window_effect_completed (MutterWindow *cw, gulong event)
case MUTTER_PLUGIN_DESTROY: case MUTTER_PLUGIN_DESTROY:
case MUTTER_PLUGIN_UNMAXIMIZE: case MUTTER_PLUGIN_UNMAXIMIZE:
case MUTTER_PLUGIN_MAXIMIZE: 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 || if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group)
priv->maximize_in_progress ||
priv->unmaximize_in_progress ||
priv->map_in_progress ||
priv->destroy_in_progress)
{ {
/* wait until last effect finished */ clutter_actor_reparent (CLUTTER_ACTOR (cw),
break; info->hidden_group);
}
else
{
clutter_actor_destroy (CLUTTER_ACTOR (cw));
return;
} }
priv->hide_after_effect = FALSE;
} }
if (priv->needs_destroy && effect_in_progress (cw, TRUE) == FALSE)
{
clutter_actor_destroy (CLUTTER_ACTOR (cw));
return;
}
default: default:
break; break;
} }
@ -1025,10 +1047,7 @@ destroy_win (MutterWindow *cw)
{ {
priv->destroy_in_progress--; priv->destroy_in_progress--;
if (priv->minimize_in_progress || if (effect_in_progress (cw, FALSE))
priv->maximize_in_progress ||
priv->unmaximize_in_progress ||
priv->map_in_progress)
{ {
priv->needs_destroy = TRUE; priv->needs_destroy = TRUE;
} }
@ -1055,10 +1074,7 @@ sync_actor_position (MutterWindow *cw)
priv->attrs.x = window_rect.x; priv->attrs.x = window_rect.x;
priv->attrs.y = window_rect.y; priv->attrs.y = window_rect.y;
if (priv->maximize_in_progress || if (effect_in_progress (cw, FALSE))
priv->unmaximize_in_progress ||
priv->minimize_in_progress ||
priv->map_in_progress)
return; return;
clutter_actor_set_position (CLUTTER_ACTOR (cw), clutter_actor_set_position (CLUTTER_ACTOR (cw),
@ -2192,6 +2208,7 @@ clutter_cmp_set_window_hidden (MetaCompositor *compositor,
gboolean hidden) gboolean hidden)
{ {
MutterWindow *cw = MUTTER_WINDOW (meta_window_get_compositor_private (window)); MutterWindow *cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
MutterWindowPrivate *priv = cw->priv;
MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaCompScreen *info = meta_screen_get_compositor_data (screen);
DEBUG_TRACE ("clutter_cmp_set_window_hidden\n"); DEBUG_TRACE ("clutter_cmp_set_window_hidden\n");
@ -2200,14 +2217,22 @@ clutter_cmp_set_window_hidden (MetaCompositor *compositor,
if (hidden) if (hidden)
{ {
/* FIXME: There needs to be a way to queue this if there is an effect if (effect_in_progress (cw, TRUE))
* in progress for this window */ {
if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group) priv->hide_after_effect = TRUE;
clutter_actor_reparent (CLUTTER_ACTOR (cw), }
info->hidden_group); else
{
if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->hidden_group)
{
clutter_actor_reparent (CLUTTER_ACTOR (cw),
info->hidden_group);
}
}
} }
else else
{ {
priv->hide_after_effect = FALSE;
if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->window_group) if (clutter_actor_get_parent (CLUTTER_ACTOR (cw)) != info->window_group)
clutter_actor_reparent (CLUTTER_ACTOR (cw), clutter_actor_reparent (CLUTTER_ACTOR (cw),
info->window_group); info->window_group);