From 924f719b978d42e6c1086558d28ba2c5d9d23052 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 23 Oct 2024 11:48:39 -0400 Subject: [PATCH] wayland: Get the window content scale from the backend The window content scale may change independently of the display it is on if scaling or accessibility features are involved, so query it directly from the backend instead of inferring it. --- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 12 +++++++++--- src/video/wayland/SDL_waylandvideo.c | 1 + src/video/wayland/SDL_waylandwindow.c | 11 +++++++++++ src/video/wayland/SDL_waylandwindow.h | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index cb5a650a18..12c4213d76 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -264,6 +264,7 @@ struct SDL_VideoDevice void (*SetWindowMaximumSize)(SDL_VideoDevice *_this, SDL_Window *window); void (*SetWindowAspectRatio)(SDL_VideoDevice *_this, SDL_Window *window); bool (*GetWindowBordersSize)(SDL_VideoDevice *_this, SDL_Window *window, int *top, int *left, int *bottom, int *right); + float (*GetWindowContentScale)(SDL_VideoDevice *_this, SDL_Window *window); void (*GetWindowSizeInPixels)(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h); bool (*SetWindowOpacity)(SDL_VideoDevice *_this, SDL_Window *window, float opacity); bool (*SetWindowParent)(SDL_VideoDevice *_this, SDL_Window *window, SDL_Window *parent); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index d8485ebf01..97c8755aa5 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1751,11 +1751,17 @@ float SDL_GetWindowDisplayScale(SDL_Window *window) static void SDL_CheckWindowDisplayScaleChanged(SDL_Window *window) { - float pixel_density = SDL_GetWindowPixelDensity(window); - float content_scale = SDL_GetDisplayContentScale(SDL_GetDisplayForWindowPosition(window)); float display_scale; - display_scale = (pixel_density * content_scale); + if (_this->GetWindowContentScale) { + display_scale = _this->GetWindowContentScale(_this, window); + } else { + const float pixel_density = SDL_GetWindowPixelDensity(window); + const float content_scale = SDL_GetDisplayContentScale(SDL_GetDisplayForWindowPosition(window)); + + display_scale = pixel_density * content_scale; + } + if (display_scale != window->display_scale) { window->display_scale = display_scale; SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED, 0, 0); diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index d93eb60b47..02952a162a 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -625,6 +625,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols) device->SetWindowTitle = Wayland_SetWindowTitle; device->SetWindowIcon = Wayland_SetWindowIcon; device->GetWindowSizeInPixels = Wayland_GetWindowSizeInPixels; + device->GetWindowContentScale = Wayland_GetWindowContentScale; device->GetDisplayForWindow = Wayland_GetDisplayForWindow; device->DestroyWindow = Wayland_DestroyWindow; device->SetWindowHitTest = Wayland_SetWindowHitTest; diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 653ca10c23..60cfa76fa5 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -2658,6 +2658,17 @@ void Wayland_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, i *h = data->current.pixel_height; } +float Wayland_GetWindowContentScale(SDL_VideoDevice *_this, SDL_Window *window) +{ + SDL_WindowData *wind = window->internal; + + if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY || wind->scale_to_display || wind->fullscreen_exclusive) { + return (float)wind->scale_factor; + } + + return 1.0f; +} + SDL_DisplayID Wayland_GetDisplayForWindow(SDL_VideoDevice *_this, SDL_Window *window) { SDL_WindowData *wind = window->internal; diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 125abc59cf..7260575762 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -208,6 +208,7 @@ extern void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y); extern void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window); extern bool Wayland_SuspendScreenSaver(SDL_VideoDevice *_this); extern bool Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon); +extern float Wayland_GetWindowContentScale(SDL_VideoDevice *_this, SDL_Window *window); extern bool Wayland_SetWindowHitTest(SDL_Window *window, bool enabled); extern bool Wayland_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);