[gtk+/gtk-3-18] gdk: Compress window state events



commit 926f82e52e8d3bb52145e728d8c4ffc30ef4146c
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Feb 26 14:10:06 2016 +0800

    gdk: Compress window state events
    
    If there are already a window state event for a given window queued
    when the window state is changed, drop that event and queue a new event
    with a changed_mask based on the state before last event that was queue
    without compression.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=762468

 gdk/gdkevents.c    |   39 +++++++++++++++++++++++++++++++++++----
 gdk/gdkinternals.h |    1 +
 2 files changed, 36 insertions(+), 4 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 4052d54..c6536a4 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -2145,12 +2145,32 @@ _gdk_event_button_generate (GdkDisplay *display,
     }
 }
 
+static GList *
+gdk_get_pending_window_state_event_link (GdkWindow *window)
+{
+  GdkDisplay *display = gdk_window_get_display (window);
+  GList *tmp_list;
+
+  for (tmp_list = display->queued_events; tmp_list; tmp_list = tmp_list->next)
+    {
+      GdkEventPrivate *event = tmp_list->data;
+
+      if (event->event.type == GDK_WINDOW_STATE &&
+          event->event.window_state.window == window)
+        return tmp_list;
+    }
+
+  return NULL;
+}
+
 void
 _gdk_set_window_state (GdkWindow      *window,
                        GdkWindowState  new_state)
 {
+  GdkDisplay *display = gdk_window_get_display (window);
   GdkEvent temp_event;
   GdkWindowState old;
+  GList *pending_event_link;
 
   g_return_if_fail (window != NULL);
 
@@ -2159,11 +2179,22 @@ _gdk_set_window_state (GdkWindow      *window,
   temp_event.window_state.send_event = FALSE;
   temp_event.window_state.new_window_state = new_state;
 
-  old = window->state;
-
-  if (temp_event.window_state.new_window_state == old)
+  if (temp_event.window_state.new_window_state == window->state)
     return; /* No actual work to do, nothing changed. */
 
+  pending_event_link = gdk_get_pending_window_state_event_link (window);
+  if (pending_event_link)
+    {
+      old = window->old_state;
+      _gdk_event_queue_remove_link (display, pending_event_link);
+      g_list_free_1 (pending_event_link);
+    }
+  else
+    {
+      old = window->state;
+      window->old_state = old;
+    }
+
   temp_event.window_state.changed_mask = new_state ^ old;
 
   /* Actually update the field in GdkWindow, this is sort of an odd
@@ -2185,7 +2216,7 @@ _gdk_set_window_state (GdkWindow      *window,
     {
     case GDK_WINDOW_TOPLEVEL:
     case GDK_WINDOW_TEMP: /* ? */
-      gdk_display_put_event (gdk_window_get_display (window), &temp_event);
+      gdk_display_put_event (display, &temp_event);
       break;
     case GDK_WINDOW_FOREIGN:
     case GDK_WINDOW_ROOT:
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 718a02d..92826c1 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -310,6 +310,7 @@ struct _GdkWindow
   /* We store the old expose areas to support buffer-age optimizations */
   cairo_region_t *old_updated_area[2];
 
+  GdkWindowState old_state;
   GdkWindowState state;
 
   guint8 alpha;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]