From f372fa29b223ac164ca52db21db69f57bdfeedba Mon Sep 17 00:00:00 2001
From: "Owen W. Taylor" <otaylor@fishsoup.net>
Date: Sat, 13 Nov 2010 14:07:07 -0500
Subject: [PATCH] MetaStackTracker: Avoid queueing resync for obvious no-ops

Since we can't distinguish a ConfigureEvent that indicates a raise
from a ConfigureEvent that indicates a move, we get lots of
STACK_OP_RAISE_ABOVE events for windows that are already in the
right place in the stacking order. Avoid queueing a restack in that
case.

https://bugzilla.gnome.org/show_bug.cgi?id=634771
---
 src/core/stack-tracker.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c
index c830fbbb9..94158079b 100644
--- a/src/core/stack-tracker.c
+++ b/src/core/stack-tracker.c
@@ -54,8 +54,8 @@
  *
  * When we receive a new event: a) we compare the serial in the event to
  * the serial of the queued requests and remove any that are now
- * no longer pending b) drop the predicted stacking order to recompute
- * it at the next opportunity.
+ * no longer pending b) if necessary, drop the predicted stacking
+ * order to recompute it at the next opportunity.
  *
  * Possible optimizations:
  *  Keep the stacks as an array + reverse-mapping hash table to avoid
@@ -505,6 +505,8 @@ static void
 stack_tracker_event_received (MetaStackTracker *tracker,
 			      MetaStackOp      *op)
 {
+  gboolean need_sync = FALSE;
+
   meta_stack_op_dump (op, "Stack op event received: ", "\n");
 
   if (op->any.serial < tracker->server_serial)
@@ -512,7 +514,8 @@ stack_tracker_event_received (MetaStackTracker *tracker,
 
   tracker->server_serial = op->any.serial;
 
-  meta_stack_op_apply (op, tracker->server_stack);
+  if (meta_stack_op_apply (op, tracker->server_stack))
+    need_sync = TRUE;
 
   while (tracker->queued_requests->head)
     {
@@ -522,17 +525,21 @@ stack_tracker_event_received (MetaStackTracker *tracker,
 
       g_queue_pop_head (tracker->queued_requests);
       meta_stack_op_free (queued_op);
+      need_sync = TRUE;
     }
 
-  if (tracker->predicted_stack)
+  if (need_sync)
     {
-      g_array_free (tracker->predicted_stack, TRUE);
-      tracker->predicted_stack = NULL;
+      if (tracker->predicted_stack)
+        {
+          g_array_free (tracker->predicted_stack, TRUE);
+          tracker->predicted_stack = NULL;
+        }
+
+      meta_stack_tracker_queue_sync_stack (tracker);
     }
 
   meta_stack_tracker_dump (tracker);
-
-  meta_stack_tracker_queue_sync_stack (tracker);
 }
 
 void