From 603ea3b3e7750e129078b90bdb77ad6eb592d59e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 16 Sep 2015 12:21:36 +0200 Subject: [PATCH] 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 | 35 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 792de22c37..92548858c1 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; - /* 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"); + 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"); + 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