[mutter] Avoid restacking animating hidden actors
- From: Owen Taylor <otaylor src gnome org>
- To: svn-commits-list gnome org
- Subject: [mutter] Avoid restacking animating hidden actors
- Date: Tue, 30 Jun 2009 13:41:57 +0000 (UTC)
commit 455486db7c1fd379e423a404f329b584318f9ede
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Fri Jun 26 17:05:11 2009 -0400
Avoid restacking animating hidden actors
Since the stack passed to the compositor now accurately reflects
the X stacking order, we need to treat hidden windows (which are
at the bottom of the X stacking order) specially - when the
compositor stacking order is synced, try to keep animating hidden
actors in their old positions in the stack.
http://bugzilla.gnome.org/show_bug.cgi?id=585984
src/compositor/mutter/compositor-mutter.c | 85 ++++++++++++++++++++++++-----
1 files changed, 72 insertions(+), 13 deletions(-)
---
diff --git a/src/compositor/mutter/compositor-mutter.c b/src/compositor/mutter/compositor-mutter.c
index 299575b..92f797a 100644
--- a/src/compositor/mutter/compositor-mutter.c
+++ b/src/compositor/mutter/compositor-mutter.c
@@ -2429,26 +2429,85 @@ clutter_cmp_sync_stack (MetaCompositor *compositor,
MetaScreen *screen,
GList *stack)
{
- GList *tmp;
+ GList *old_stack;
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
DEBUG_TRACE ("clutter_cmp_sync_stack\n");
- /* NB: The first entry in stack, is stacked the highest */
- for (tmp = stack; tmp != NULL; tmp = tmp->next)
+ /* This is painful because hidden windows that we are in the process
+ * of animating out of existence. They'll be at the bottom of the
+ * stack of X windows, but we want to leave them in their old position
+ * until the animation effect finishes.
+ */
+
+ /* Sources: first window is the highest */
+ stack = g_list_copy (stack); /* The new stack of MetaWindow */
+ old_stack = g_list_reverse (info->windows); /* The old stack of MutterWindow */
+ info->windows = NULL;
+
+ while (TRUE)
{
- MetaWindow *window = tmp->data;
- MutterWindow *cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
+ MutterWindow *old_actor = NULL, *stack_actor = NULL, *actor;
+ MetaWindow *old_window = NULL, *stack_window = NULL, *window;
- if (!cw)
- {
- meta_verbose ("Failed to find corresponding MutterWindow "
- "for window %p\n", window);
- continue;
- }
+ /* Find the remaining top actor in our existing stack (ignoring
+ * windows that have been hidden and are no longer animating) */
+ while (old_stack)
+ {
+ old_actor = old_stack->data;
+ old_window = mutter_window_get_meta_window (old_actor);
+
+ if (old_window->hidden &&
+ !effect_in_progress (old_actor, TRUE))
+ old_stack = g_list_delete_link (old_stack, old_stack);
+ else
+ break;
+ }
+
+ /* And the remaining top actor in the new stack */
+ while (stack)
+ {
+ stack_window = stack->data;
+ stack_actor = MUTTER_WINDOW (meta_window_get_compositor_private (stack_window));
+ if (!stack_actor)
+ {
+ meta_verbose ("Failed to find corresponding MutterWindow "
+ "for window %s\n", meta_window_get_description (stack_window));
+ stack = g_list_delete_link (stack, stack);
+ }
+ else
+ break;
+ }
+
+ if (!old_actor && !stack_actor) /* Nothing more to stack */
+ break;
+
+ /* We usually prefer the window in the new stack, but if if we
+ * found a hidden window in the process of being animated out
+ * of existence in the old stack we use that instead. We've
+ * filtered out non-animating hidden windows above.
+ */
+ if (old_actor &&
+ (!stack_actor || old_window->hidden))
+ {
+ actor = old_actor;
+ window = old_window;
+ }
+ else
+ {
+ actor = stack_actor;
+ window = stack_window;
+ }
+
+ /* OK, we know what actor we want next. Add it to our window
+ * list, and remove it from both source lists. (It will
+ * be at the front of at least one, hopefully it will be
+ * near the front of the other.)
+ */
+ info->windows = g_list_prepend (info->windows, actor);
- info->windows = g_list_remove (info->windows, (gconstpointer)cw);
- info->windows = g_list_prepend (info->windows, cw);
+ stack = g_list_remove (stack, window);
+ old_stack = g_list_remove (old_stack, actor);
}
sync_actor_stacking (info->windows);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]