[PATCH weston] input: Don't recreate the cursor sprite when only the hotspot changes

Derek Foreman derekf at osg.samsung.com
Fri Mar 20 14:44:41 PDT 2015


Currently we unmap and re-map the cursor when the hotspot changes which
causes spurious enter/leave events.

This changes the pointer_set_cursor() logic to avoid this.

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
---
 src/input.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/src/input.c b/src/input.c
index 469d5ce..a24ae1a 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1632,6 +1632,7 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
 {
 	struct weston_pointer *pointer = wl_resource_get_user_data(resource);
 	struct weston_surface *surface = NULL;
+	bool full_set = true;
 
 	if (surface_resource)
 		surface = wl_resource_get_user_data(surface_resource);
@@ -1648,31 +1649,43 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
 	if (pointer->focus_serial - serial > UINT32_MAX / 2)
 		return;
 
-	if (surface) {
-		if (weston_surface_set_role(surface, "wl_pointer-cursor",
-					    resource,
-					    WL_POINTER_ERROR_ROLE) < 0)
-			return;
+	if (!surface) {
+		if (pointer->sprite)
+			pointer_unmap_sprite(pointer);
+		return;
 	}
 
+	/* Nothing changed.  Unmapping and recreating the cursor sprite
+	 * generates extra enter and leave events, so we avoid it if
+	 * at all possible.
+	 */
 	if (pointer->sprite && pointer->sprite->surface == surface &&
 	    pointer->hotspot_x == x && pointer->hotspot_y == y)
 		return;
 
-	if (pointer->sprite)
-		pointer_unmap_sprite(pointer);
+	/* Only the hotspot changed. */
+	if (pointer->sprite && pointer->sprite->surface == surface)
+		full_set = false;
 
-	if (!surface)
-		return;
+	if (full_set) {
+		if (weston_surface_set_role(surface, "wl_pointer-cursor",
+					    resource,
+					    WL_POINTER_ERROR_ROLE) < 0)
+			return;
 
-	wl_signal_add(&surface->destroy_signal,
-		      &pointer->sprite_destroy_listener);
+		if (pointer->sprite)
+			pointer_unmap_sprite(pointer);
+
+		wl_signal_add(&surface->destroy_signal,
+			      &pointer->sprite_destroy_listener);
+
+		surface->configure = pointer_cursor_surface_configure;
+		surface->configure_private = pointer;
+		weston_surface_set_label_func(surface,
+					    pointer_cursor_surface_get_label);
+		pointer->sprite = weston_view_create(surface);
+	}
 
-	surface->configure = pointer_cursor_surface_configure;
-	surface->configure_private = pointer;
-	weston_surface_set_label_func(surface,
-				      pointer_cursor_surface_get_label);
-	pointer->sprite = weston_view_create(surface);
 	pointer->hotspot_x = x;
 	pointer->hotspot_y = y;
 
-- 
2.1.4



More information about the wayland-devel mailing list