Browse Source

wayland: Use high-DPI system cursors on non-DPI aware windows

Using an unscaled buffer just results in the compositor scaling up the low-res cursor image for output, resulting in it appearing blurry. Always use the scaled cursor to ensure that it appears sharp and matches the native system look.
Frank Praznik 10 months ago
parent
commit
d0c9c008e1
1 changed files with 16 additions and 13 deletions
  1. 16 13
      src/video/wayland/SDL_waylandwindow.c

+ 16 - 13
src/video/wayland/SDL_waylandwindow.c

@@ -48,6 +48,11 @@
 #include <libdecor.h>
 #endif
 
+static double GetWindowScale(SDL_Window *window)
+{
+    return (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) || window->internal->scale_to_display ? window->internal->scale_factor : 1.0;
+}
+
 // These are point->pixel->point round trip safe; the inverse is not round trip safe due to rounding.
 static int PointToPixel(SDL_Window *window, int point)
 {
@@ -55,12 +60,12 @@ static int PointToPixel(SDL_Window *window, int point)
      * Wayland scale units are in units of 1/120, so the offset is required to correct for
      * rounding errors when using certain scale values.
      */
-    return SDL_max((int)SDL_lround((double)point * window->internal->scale_factor + 1e-6), 1);
+    return SDL_max((int)SDL_lround((double)point * GetWindowScale(window) + 1e-6), 1);
 }
 
 static int PixelToPoint(SDL_Window *window, int pixel)
 {
-    return SDL_max((int)SDL_lround((double)pixel / window->internal->scale_factor), 1);
+    return SDL_max((int)SDL_lround((double)pixel / GetWindowScale(window)), 1);
 }
 
 /* According to the Wayland spec:
@@ -295,6 +300,7 @@ static void SetSurfaceOpaqueRegion(SDL_WindowData *wind, bool is_opaque)
 static void ConfigureWindowGeometry(SDL_Window *window)
 {
     SDL_WindowData *data = window->internal;
+    const double scale_factor = GetWindowScale(window);
     const int old_pixel_width = data->current.pixel_width;
     const int old_pixel_height = data->current.pixel_height;
     int window_width, window_height;
@@ -381,7 +387,7 @@ static void ConfigureWindowGeometry(SDL_Window *window)
                 wp_viewport_set_destination(data->viewport, window_width, window_height);
             } else if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
                 // Don't change this if the DPI awareness flag is unset, as an application may have set this manually on a custom or external surface.
-                wl_surface_set_buffer_scale(data->surface, (int32_t)data->scale_factor);
+                wl_surface_set_buffer_scale(data->surface, (int32_t)scale_factor);
             }
 
             // Clamp the physical window size to the system minimum required size.
@@ -392,8 +398,8 @@ static void ConfigureWindowGeometry(SDL_Window *window)
                 data->pointer_scale.x = 1.0;
                 data->pointer_scale.y = 1.0;
             } else {
-                data->pointer_scale.x = data->scale_factor;
-                data->pointer_scale.y = data->scale_factor;
+                data->pointer_scale.x = scale_factor;
+                data->pointer_scale.y = scale_factor;
             }
         }
     }
@@ -1345,11 +1351,6 @@ static void Wayland_HandlePreferredScaleChanged(SDL_WindowData *window_data, dou
 {
     const double old_factor = window_data->scale_factor;
 
-    if (!(window_data->sdlwindow->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) && !window_data->scale_to_display) {
-        // Scale will always be 1, just ignore this
-        return;
-    }
-
     // Round the scale factor if viewports aren't available.
     if (!window_data->viewport) {
         factor = SDL_ceil(factor);
@@ -1372,8 +1373,10 @@ static void Wayland_HandlePreferredScaleChanged(SDL_WindowData *window_data, dou
             }
         }
 
-        ConfigureWindowGeometry(window_data->sdlwindow);
-        CommitLibdecorFrame(window_data->sdlwindow);
+        if (window_data->sdlwindow->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY || window_data->scale_to_display) {
+            ConfigureWindowGeometry(window_data->sdlwindow);
+            CommitLibdecorFrame(window_data->sdlwindow);
+        }
     }
 }
 
@@ -2398,7 +2401,7 @@ bool Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Proper
         data->scale_to_display = window->parent->internal->scale_to_display;
         data->scale_factor = window->parent->internal->scale_factor;
         EnsurePopupPositionIsValid(window, &window->x, &window->y);
-    } else if ((window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) || c->scale_to_display_enabled) {
+    } else {
         for (int i = 0; i < _this->num_displays; i++) {
             data->scale_factor = SDL_max(data->scale_factor, _this->displays[i]->internal->scale_factor);
         }