]> Pileus Git - ~andy/gtk/commitdiff
Keep the length of the anti-expose queue finite, by if it gets too long,
authorOwen Taylor <otaylor@redhat.com>
Wed, 6 Feb 2002 00:41:07 +0000 (00:41 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Wed, 6 Feb 2002 00:41:07 +0000 (00:41 +0000)
Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>

        * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
        the length of the anti-expose queue finite, by if
        it gets too long, first doing a XSync() and checking
the event queue, and if that doesn't work, simply
        discarding all anti-expose items in the queue.

* gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
on ConfigureNotify (#56349, Thomas Leonard)

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/x11/gdkdnd-x11.c
gdk/x11/gdkgeometry-x11.c

index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index 11dd9b493b250b54a3f3cd6f96b76733e5fd9731..f707e21c63d76a1631f05c70f33067b26433a6cb 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb  5 19:13:42 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkgeometry-x11.c (gdk_window_queue): Keep
+       the length of the anti-expose queue finite, by if
+       it gets too long, first doing a XSync() and checking
+       the event queue, and if that doesn't work, simply
+       discarding all anti-expose items in the queue.
+
+       * gdk/x11/gdkdnd-x11.c (gdk_window_cache_filter): Fix ordering
+       on ConfigureNotify (#56349, Thomas Leonard)
+
 2002-02-05  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkimage.c (gtk_image_expose): offset area being gotten from
index f7ffbd9db04c24282c66395840c87472c23049e5..fd61beeedd74def7607c131fe54dac17ec709d6a 100644 (file)
@@ -329,12 +329,14 @@ gdk_window_cache_filter (GdkXEvent *xev,
                                                         GUINT_TO_POINTER (xce->above));
                if (above_node && node->prev != above_node)
                  {
+                   /* Put the window above (before in the list) above_node
+                    */
                    cache->children = g_list_remove_link (cache->children, node);
-                   node->next = above_node->next;
-                   if (node->next)
-                     node->next->prev = node;
-                   node->prev = above_node;
-                   above_node->next = node;
+                   node->prev = above_node->prev;
+                   if (node->prev)
+                     node->prev->next = node;
+                   node->next = above_node;
+                   above_node->prev = node;
                  }
              }
          }
index db1fc2cfe4fcb2c5ea1e1bf6f78b826fc4281070..7859c8633ba3f63a2491ebd99fb9d03c762b69a8 100644 (file)
@@ -186,7 +186,7 @@ static void gdk_window_clip_changed       (GdkWindow          *window,
                                           GdkRectangle       *old_clip,
                                           GdkRectangle       *new_clip);
 
-static GSList *translate_queue = NULL;
+static GQueue *translate_queue = NULL;
 
 void
 _gdk_windowing_window_get_offsets (GdkWindow *window,
@@ -860,20 +860,132 @@ gdk_window_postmove (GdkWindow          *window,
     }
 }
 
+Bool
+expose_serial_predicate (Display *xdisplay,
+                        XEvent  *xev,
+                        XPointer arg)
+{
+  gulong *serial = (gulong *)arg;
+
+  if (xev->xany.type == Expose)
+    *serial = MIN (*serial, xev->xany.serial);
+
+  return False;
+}
+
+/* Find oldest possible serial for an outstanding expose event
+ */
+static gulong
+find_current_serial (Display *xdisplay)
+{
+  XEvent xev;
+  gulong serial = NextRequest (xdisplay);
+  
+  XSync (xdisplay, False);
+
+  XCheckIfEvent (xdisplay, &xev, expose_serial_predicate, (XPointer)&serial);
+
+  return serial;
+}
+
+static void
+queue_delete_link (GQueue *queue,
+                  GList  *link)
+{
+  if (queue->tail == link)
+    queue->tail = link->prev;
+  
+  queue->head = g_list_remove_link (queue->head, link);
+  g_list_free_1 (link);
+  queue->length--;
+}
+
+static void
+queue_item_free (GdkWindowQueueItem *item)
+{
+  gdk_drawable_unref (item->window);
+  
+  if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
+    gdk_region_destroy (item->u.antiexpose.area);
+  
+  g_free (item);
+}
+
+static void
+gdk_window_queue (GdkWindow          *window,
+                 GdkWindowQueueItem *item)
+{
+  if (!translate_queue)
+    translate_queue = g_queue_new ();
+
+  /* Keep length of queue finite by, if it grows too long,
+   * figuring out the latest relevant serial and discarding
+   * irrelevant queue items.
+   */
+  if (translate_queue->length >= 64 )
+    {
+      gulong serial = find_current_serial (GDK_WINDOW_XDISPLAY (window));
+      GList *tmp_list = translate_queue->head;
+      
+      while (tmp_list)
+       {
+         GdkWindowQueueItem *item = tmp_list->data;
+         GList *next = tmp_list->next;
+         
+         if (serial > item->serial)
+           {
+             queue_delete_link (translate_queue, tmp_list);
+             queue_item_free (item);
+           }
+
+         tmp_list = next;
+       }
+    }
+
+  /* Catch the case where someone isn't processing events and there
+   * is an event stuck in the event queue with an old serial:
+   * If we can't reduce the queue length by the above method,
+   * discard anti-expose items. (We can't discard translate
+   * items 
+   */
+  if (translate_queue->length >= 64 )
+    {
+      GList *tmp_list = translate_queue->head;
+      
+      while (tmp_list)
+       {
+         GdkWindowQueueItem *item = tmp_list->data;
+         GList *next = tmp_list->next;
+         
+         if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
+           {
+             queue_delete_link (translate_queue, tmp_list);
+             queue_item_free (item);
+           }
+
+         tmp_list = next;
+       }
+    }
+      
+  gdk_drawable_ref (window);
+
+  item->window = window;
+  item->serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
+  
+  g_queue_push_tail (translate_queue, item);
+}
+
 static void
 gdk_window_queue_translation (GdkWindow *window,
                              gint       dx,
                              gint       dy)
 {
   GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
-  item->window = window;
-  item->serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
   item->type = GDK_WINDOW_QUEUE_TRANSLATE;
   item->u.translate.dx = dx;
   item->u.translate.dy = dy;
 
-  gdk_drawable_ref (window);
-  translate_queue = g_slist_append (translate_queue, item);
+  gdk_window_queue (window, item);
 }
 
 gboolean
@@ -881,13 +993,10 @@ _gdk_windowing_window_queue_antiexpose (GdkWindow *window,
                                        GdkRegion *area)
 {
   GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
-  item->window = window;
-  item->serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
   item->type = GDK_WINDOW_QUEUE_ANTIEXPOSE;
   item->u.antiexpose.area = area;
 
-  gdk_drawable_ref (window);
-  translate_queue = g_slist_append (translate_queue, item);
+  gdk_window_queue (window, item);
 
   return TRUE;
 }
@@ -900,37 +1009,33 @@ _gdk_window_process_expose (GdkWindow    *window,
   GdkWindowImplX11 *impl;
   GdkRegion *invalidate_region = gdk_region_rectangle (area);
   GdkRegion *clip_region;
-  GSList *tmp_list = translate_queue;
-  
+
   impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl);
-  
-  while (tmp_list)
+      
+  if (translate_queue)
     {
-      GdkWindowQueueItem *item = tmp_list->data;
-      tmp_list = tmp_list->next;
-
-      if (serial < item->serial)
+      GList *tmp_list = translate_queue->head;
+      
+      while (tmp_list)
        {
-         if (item->window == window)
+         GdkWindowQueueItem *item = tmp_list->data;
+         tmp_list = tmp_list->next;
+         
+         if (serial < item->serial)
            {
-             if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
-               gdk_region_offset (invalidate_region, item->u.translate.dx, item->u.translate.dy);
-             else              /* anti-expose */
-               gdk_region_subtract (invalidate_region, item->u.antiexpose.area);
+             if (item->window == window)
+               {
+                 if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
+                   gdk_region_offset (invalidate_region, item->u.translate.dx, item->u.translate.dy);
+                 else          /* anti-expose */
+                   gdk_region_subtract (invalidate_region, item->u.antiexpose.area);
+               }
+           }
+         else
+           {
+             queue_delete_link (translate_queue, translate_queue->head);
+             queue_item_free (item);
            }
-       }
-      else
-       {
-         GSList *tmp_link = translate_queue;
-         
-         translate_queue = g_slist_remove_link (translate_queue, translate_queue);
-         gdk_drawable_unref (item->window);
-
-         if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
-           gdk_region_destroy (item->u.antiexpose.area);
-         
-         g_free (item);
-         g_slist_free_1 (tmp_link);
        }
     }