[gtk+] wayland: Avoid running stale cursor animation timeouts



commit 603ea3b3e7750e129078b90bdb77ad6eb592d59e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Sep 16 12:21:36 2015 +0200

    wayland: Avoid running stale cursor animation timeouts
    
    gdk_wayland_device_update_window_cursor() is inconsistently returning
    TRUE/FALSE, despite the timeout being always replaced for new cursor
    frames. This could end up in these timeouts being "leaked" and running
    as long as the window has an animated cursor.
    
    Fix this by making it really sure we return G_SOURCE_REMOVE, although
    now we keep track of animation delays, so the timeout will be reused
    for constant time animations.

 gdk/wayland/gdkdevice-wayland.c |   37 ++++++++++++++++++++++++-------------
 1 files changed, 24 insertions(+), 13 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 792de22..9254885 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -94,6 +94,7 @@ struct _GdkWaylandDeviceData
   GdkCursor *grab_cursor;
   guint cursor_timeout_id;
   guint cursor_image_index;
+  guint cursor_image_delay;
 
   GdkDragContext *drop_context;
 
@@ -188,6 +189,7 @@ gdk_wayland_device_stop_window_cursor_animation (GdkWaylandDeviceData *wd)
       wd->cursor_timeout_id = 0;
     }
   wd->cursor_image_index = 0;
+  wd->cursor_image_delay = 0;
 }
 
 static gboolean
@@ -196,6 +198,7 @@ gdk_wayland_device_update_window_cursor (GdkWaylandDeviceData *wd)
   struct wl_buffer *buffer;
   int x, y, w, h, scale;
   guint next_image_index, next_image_delay;
+  gboolean retval = G_SOURCE_REMOVE;
 
   if (wd->grab_cursor)
     {
@@ -210,11 +213,11 @@ gdk_wayland_device_update_window_cursor (GdkWaylandDeviceData *wd)
   else
     {
       wd->cursor_timeout_id = 0;
-      return TRUE;
+      return retval;
     }
 
   if (!wd->wl_pointer)
-    return FALSE;
+    return retval;
 
   wl_pointer_set_cursor (wd->wl_pointer,
                          wd->enter_serial,
@@ -232,7 +235,7 @@ gdk_wayland_device_update_window_cursor (GdkWaylandDeviceData *wd)
     {
       /* We admit only static icons during drags so far */
       gdk_wayland_device_stop_window_cursor_animation (wd);
-      return TRUE;
+      return retval;
     }
 
   next_image_index =
@@ -242,21 +245,29 @@ gdk_wayland_device_update_window_cursor (GdkWaylandDeviceData *wd)
 
   if (next_image_index != wd->cursor_image_index)
     {
-      guint id;
+      if (next_image_delay != wd->cursor_image_delay)
+        {
+          guint id;
+
+          gdk_wayland_device_stop_window_cursor_animation (wd);
 
-      /* Queue timeout for next frame */
-      id = g_timeout_add (next_image_delay,
-                          (GSourceFunc)gdk_wayland_device_update_window_cursor,
-                          wd);
-      g_source_set_name_by_id (id, "[gtk+] gdk_wayland_device_update_window_cursor");
+          /* Queue timeout for next frame */
+          id = g_timeout_add (next_image_delay,
+                              (GSourceFunc)gdk_wayland_device_update_window_cursor,
+                              wd);
+          g_source_set_name_by_id (id, "[gtk+] gdk_wayland_device_update_window_cursor");
+          wd->cursor_timeout_id = id;
+        }
+      else
+        retval = G_SOURCE_CONTINUE;
 
-      wd->cursor_timeout_id = id;
       wd->cursor_image_index = next_image_index;
+      wd->cursor_image_delay = next_image_delay;
     }
   else
-    wd->cursor_timeout_id = 0;
+    gdk_wayland_device_stop_window_cursor_animation (wd);
 
-  return FALSE;
+  return retval;
 }
 
 static void


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