Browse Source

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.
Frank Praznik 10 months ago
parent
commit
7ca0e9ede1
1 changed files with 14 additions and 16 deletions
  1. 14 16
      src/video/wayland/SDL_waylandmouse.c

+ 14 - 16
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;
     *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) {
         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;
             *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 {
         } else {
-            // No exact match, and viewports are unsupported. Find a safe integer scale.
             for (; *scale > 1; --*scale) {
             for (; *scale > 1; --*scale) {
                 if (cursor->images[0]->width % *scale == 0) {
                 if (cursor->images[0]->width % *scale == 0) {
                     break;
                     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;
     return true;
 }
 }