From 924f719b978d42e6c1086558d28ba2c5d9d23052 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
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 cb5a650a185d4..12c4213d766fd 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 d8485ebf01f0e..97c8755aa5c54 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 d93eb60b4794e..02952a162ae00 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 653ca10c23ef3..60cfa76fa5840 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 125abc59cf73f..7260575762885 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);