From 7ca0e9ede151aaa8ab2d3f835fbb3437181c82ff Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 28 Sep 2024 14:29:24 -0400
Subject: [PATCH] wayland: Scale the pointer destination size relative to the
theme size
This better matches compositor behavior and avoids slight size jumps when the cursor enters and leaves the window.
---
src/video/wayland/SDL_waylandmouse.c | 30 +++++++++++++---------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c
index 6e9b0122b7b24..3c35424a2b35d 100644
--- a/src/video/wayland/SDL_waylandmouse.c
+++ b/src/video/wayland/SDL_waylandmouse.c
@@ -423,34 +423,32 @@ static bool Wayland_GetSystemCursor(SDL_VideoData *vdata, SDL_CursorData *cdata,
}
*scale = SDL_ceil(scale_factor) == scale_factor ? (int)scale_factor : 0;
- *dst_size = theme_size;
- // Calculate the hotspot offset if the cursor is being scaled.
- if (scaled_size == cursor->images[0]->width) {
- // If the theme has an exact size match, just divide by the scale.
- *hot_x = (int)SDL_lround(cursor->images[0]->hotspot_x / scale_factor);
- *hot_y = (int)SDL_lround(cursor->images[0]->hotspot_y / scale_factor);
- } else {
+ if (scaled_size != cursor->images[0]->width) {
+ /* If the cursor size isn't an exact match for the target size, use a viewport
+ * to avoid a possible "Buffer size is not divisible by scale" protocol error.
+ *
+ * If viewports are unavailable, find an integer scale that works.
+ */
if (vdata->viewporter) {
- // Use a viewport if no exact size match is found to avoid a potential "buffer size is not divisible by scale" protocol error.
+ // A scale of 0 indicates that a viewport set to the destination size should be used.
*scale = 0;
-
- // Map the hotspot coordinates from the source to destination sizes.
- const double hotspot_scale = (double)theme_size / (double)cursor->images[0]->width;
- *hot_x = (int)SDL_lround(hotspot_scale * cursor->images[0]->hotspot_x);
- *hot_y = (int)SDL_lround(hotspot_scale * cursor->images[0]->hotspot_y);
} else {
- // No exact match, and viewports are unsupported. Find a safe integer scale.
for (; *scale > 1; --*scale) {
if (cursor->images[0]->width % *scale == 0) {
break;
}
}
- *hot_x = cursor->images[0]->hotspot_x / *scale;
- *hot_y = cursor->images[0]->hotspot_y / *scale;
+ // Set the scale factor to the new value for the hotspot calculations.
+ scale_factor = *scale;
}
}
+ *dst_size = (int)SDL_lround(cursor->images[0]->width / scale_factor);
+
+ *hot_x = (int)SDL_lround(cursor->images[0]->hotspot_x / scale_factor);
+ *hot_y = (int)SDL_lround(cursor->images[0]->hotspot_y / scale_factor);
+
return true;
}