From ab76f040c4b8f56184ba7377a7f4bdeb079fabe5 Mon Sep 17 00:00:00 2001 From: eafton Date: Fri, 10 Oct 2025 01:02:49 +0300 Subject: [PATCH] Set content and UI scales to 1 if the retrieved value is smaller than 1 (#14193) --- src/video/x11/SDL_x11modes.c | 24 +++--- src/video/x11/SDL_x11modes.h | 5 +- src/video/x11/SDL_x11settings.c | 15 ++-- src/video/x11/SDL_x11settings.h | 2 + src/video/x11/SDL_x11toolkit.c | 125 ++------------------------------ 5 files changed, 36 insertions(+), 135 deletions(-) diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index cab71150c0..2260fbf856 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -48,7 +48,7 @@ */ // #define XRANDR_DISABLED_BY_DEFAULT -float X11_GetGlobalContentScale(SDL_VideoDevice *_this) +float X11_GetGlobalContentScale(Display *display, XSettingsClient *client) { double scale_factor = 0.0; @@ -64,19 +64,18 @@ float X11_GetGlobalContentScale(SDL_VideoDevice *_this) // If that failed, try "Xft.dpi" from the XResourcesDatabase... // We attempt to read this directly to get the live value, XResourceManagerString // is cached per display connection. - if (scale_factor <= 0.0) - { - SDL_VideoData *data = _this->internal; - Display *display = data->display; + if (scale_factor <= 0.0) { int status, real_format; Atom real_type; + Atom res_mgr; unsigned long items_read, items_left; char *resource_manager; bool owns_resource_manager = false; X11_XrmInitialize(); + res_mgr = X11_XInternAtom(display, "RESOURCE_MANAGER", False); status = X11_XGetWindowProperty(display, RootWindow(display, DefaultScreen(display)), - data->atoms.RESOURCE_MANAGER, 0L, 8192L, False, XA_STRING, + res_mgr, 0L, 8192L, False, XA_STRING, &real_type, &real_format, &items_read, &items_left, (unsigned char **)&resource_manager); @@ -112,11 +111,11 @@ float X11_GetGlobalContentScale(SDL_VideoDevice *_this) // If that failed, try the XSETTINGS keys... if (scale_factor <= 0.0) { - scale_factor = X11_GetXsettingsIntKey(_this, "Gdk/WindowScalingFactor", -1); + scale_factor = X11_GetXsettingsClientIntKey(client, "Gdk/WindowScalingFactor", -1); // The Xft/DPI key is stored in increments of 1024th if (scale_factor <= 0.0) { - int dpi = X11_GetXsettingsIntKey(_this, "Xft/DPI", -1); + int dpi = X11_GetXsettingsClientIntKey(client, "Xft/DPI", -1); if (dpi > 0) { scale_factor = (double) dpi / 1024.0; scale_factor /= 96.0; @@ -140,6 +139,11 @@ float X11_GetGlobalContentScale(SDL_VideoDevice *_this) return (float)scale_factor; } +float X11_GetGlobalContentScaleForDevice(SDL_VideoDevice *_this) +{ + return X11_GetGlobalContentScale(_this->internal->display, _this->internal->xsettings_data.xsettings); +} + static bool get_visualinfo(Display *display, int screen, XVisualInfo *vinfo) { const char *visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_VISUALID); @@ -312,7 +316,7 @@ static SDL_DisplayID X11_AddGenericDisplay(SDL_VideoDevice *_this, bool send_eve display.name = (char *)"Generic X11 Display"; /* this is just copied and thrown away, it's safe to cast to char* here. */ display.desktop_mode = mode; display.internal = displaydata; - display.content_scale = X11_GetGlobalContentScale(_this); + display.content_scale = X11_GetGlobalContentScaleForDevice(_this); return SDL_AddVideoDisplay(&display, send_event); } @@ -599,7 +603,7 @@ static bool X11_FillXRandRDisplayInfo(SDL_VideoDevice *_this, Display *dpy, int display->name = display_name; } display->desktop_mode = mode; - display->content_scale = X11_GetGlobalContentScale(_this); + display->content_scale = X11_GetGlobalContentScaleForDevice(_this); display->internal = displaydata; return true; diff --git a/src/video/x11/SDL_x11modes.h b/src/video/x11/SDL_x11modes.h index 77f445ace7..3d07a33070 100644 --- a/src/video/x11/SDL_x11modes.h +++ b/src/video/x11/SDL_x11modes.h @@ -23,6 +23,8 @@ #ifndef SDL_x11modes_h_ #define SDL_x11modes_h_ +#include "SDL_x11settings.h" + struct SDL_DisplayData { int screen; @@ -62,7 +64,8 @@ extern SDL_PixelFormat X11_GetPixelFormatFromVisualInfo(Display *display, XVisua extern bool X11_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *sdl_display, SDL_Rect *rect); extern bool X11_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *sdl_display, SDL_Rect *rect); -extern float X11_GetGlobalContentScale(SDL_VideoDevice *_this); +extern float X11_GetGlobalContentScale(Display *display, XSettingsClient *client); +extern float X11_GetGlobalContentScaleForDevice(SDL_VideoDevice *_this); #ifdef SDL_VIDEO_DRIVER_X11_XRANDR extern void X11_HandleXRandREvent(SDL_VideoDevice *_this, const XEvent *xevent); diff --git a/src/video/x11/SDL_x11settings.c b/src/video/x11/SDL_x11settings.c index da8b794405..a002cb407f 100644 --- a/src/video/x11/SDL_x11settings.c +++ b/src/video/x11/SDL_x11settings.c @@ -29,7 +29,7 @@ static void UpdateContentScale(SDL_VideoDevice *_this) { if (_this) { - float scale_factor = X11_GetGlobalContentScale(_this); + float scale_factor = X11_GetGlobalContentScaleForDevice(_this); for (int i = 0; i < _this->num_displays; ++i) { SDL_SetDisplayContentScale(_this->displays[i], scale_factor); } @@ -77,15 +77,12 @@ void X11_HandleXsettingsEvent(SDL_VideoDevice *_this, const XEvent *xevent) } } -int X11_GetXsettingsIntKey(SDL_VideoDevice *_this, const char *key, int fallback_value) { - SDL_VideoData *data = _this->internal; - SDLX11_SettingsData *xsettings_data = &data->xsettings_data; +int X11_GetXsettingsClientIntKey(XSettingsClient *client, const char *key, int fallback_value) { XSettingsSetting *setting = NULL; int res = fallback_value; - - if (xsettings_data->xsettings) { - if (xsettings_client_get_setting(xsettings_data->xsettings, key, &setting) != XSETTINGS_SUCCESS) { + if (client) { + if (xsettings_client_get_setting(client, key, &setting) != XSETTINGS_SUCCESS) { goto no_key; } @@ -104,4 +101,8 @@ no_key: return res; } +int X11_GetXsettingsIntKey(SDL_VideoDevice *_this, const char *key, int fallback_value) { + return X11_GetXsettingsClientIntKey(_this->internal->xsettings_data.xsettings, key, fallback_value); +} + #endif // SDL_VIDEO_DRIVER_X11 diff --git a/src/video/x11/SDL_x11settings.h b/src/video/x11/SDL_x11settings.h index 2dab71e058..41424656ec 100644 --- a/src/video/x11/SDL_x11settings.h +++ b/src/video/x11/SDL_x11settings.h @@ -40,4 +40,6 @@ extern void X11_QuitXsettings(SDL_VideoDevice *_this); extern void X11_HandleXsettingsEvent(SDL_VideoDevice *_this, const XEvent *xevent); extern int X11_GetXsettingsIntKey(SDL_VideoDevice *_this, const char *key, int fallback_value); +extern int X11_GetXsettingsClientIntKey(XSettingsClient *client, const char *key, int fallback_value); + #endif // SDL_x11settings_h_ diff --git a/src/video/x11/SDL_x11toolkit.c b/src/video/x11/SDL_x11toolkit.c index 3790d2894a..6ffba8e465 100644 --- a/src/video/x11/SDL_x11toolkit.c +++ b/src/video/x11/SDL_x11toolkit.c @@ -192,121 +192,6 @@ static int X11Toolkit_SharedMemoryErrorHandler(Display *d, XErrorEvent *e) return g_old_error_handler(d, e); } -int X11Toolkit_SettingsGetInt(XSettingsClient *client, const char *key, int fallback_value) { - XSettingsSetting *setting = NULL; - int res = fallback_value; - - if (client) { - if (xsettings_client_get_setting(client, key, &setting) != XSETTINGS_SUCCESS) { - goto no_key; - } - - if (setting->type != XSETTINGS_TYPE_INT) { - goto no_key; - } - - res = setting->data.v_int; - } - -no_key: - if (setting) { - xsettings_setting_free(setting); - } - - return res; -} - -static float X11Toolkit_GetUIScale(XSettingsClient *client, Display *display) -{ - double scale_factor = 0.0; - - // First use the forced scaling factor specified by the app/user - const char *hint = SDL_GetHint(SDL_HINT_VIDEO_X11_SCALING_FACTOR); - if (hint && *hint) { - double value = SDL_atof(hint); - if (value >= 1.0f && value <= 10.0f) { - scale_factor = value; - } - } - - // If that failed, try "Xft.dpi" from the XResourcesDatabase... - // We attempt to read this directly to get the live value, XResourceManagerString - // is cached per display connection. - if (scale_factor <= 0.0) { - int status, real_format; - Atom real_type; - Atom res_mgr; - unsigned long items_read, items_left; - char *resource_manager; - bool owns_resource_manager = false; - - X11_XrmInitialize(); - res_mgr = X11_XInternAtom(display, "RESOURCE_MANAGER", False); - status = X11_XGetWindowProperty(display, RootWindow(display, DefaultScreen(display)), - res_mgr, 0L, 8192L, False, XA_STRING, - &real_type, &real_format, &items_read, &items_left, - (unsigned char **)&resource_manager); - - if (status == Success && resource_manager) { - owns_resource_manager = true; - } else { - // Fall back to XResourceManagerString. This will not be updated if the - // dpi value is later changed but should allow getting the initial value. - resource_manager = X11_XResourceManagerString(display); - } - - if (resource_manager) { - XrmDatabase db; - XrmValue value; - char *type; - - db = X11_XrmGetStringDatabase(resource_manager); - - // Get the value of Xft.dpi from the Database - if (X11_XrmGetResource(db, "Xft.dpi", "String", &type, &value)) { - if (value.addr && type && SDL_strcmp(type, "String") == 0) { - int dpi = SDL_atoi(value.addr); - scale_factor = dpi / 96.0; - } - } - X11_XrmDestroyDatabase(db); - - if (owns_resource_manager) { - X11_XFree(resource_manager); - } - } - } - - // If that failed, try the XSETTINGS keys... - if (scale_factor <= 0.0) { - scale_factor = X11Toolkit_SettingsGetInt(client, "Gdk/WindowScalingFactor", -1); - - // The Xft/DPI key is stored in increments of 1024th - if (scale_factor <= 0.0) { - int dpi = X11Toolkit_SettingsGetInt(client, "Xft/DPI", -1); - if (dpi > 0) { - scale_factor = (double) dpi / 1024.0; - scale_factor /= 96.0; - } - } - } - - // If that failed, try the GDK_SCALE envvar... - if (scale_factor <= 0.0) { - const char *scale_str = SDL_getenv("GDK_SCALE"); - if (scale_str) { - scale_factor = SDL_atoi(scale_str); - } - } - - // Nothing or a bad value, just fall back to 1.0 - if (scale_factor <= 0.0) { - scale_factor = 1.0; - } - - return (float)scale_factor; -} - static void X11Toolkit_InitWindowPixmap(SDL_ToolkitWindowX11 *data) { if (data->pixmap) { #ifndef NO_SHARED_MEMORY @@ -467,8 +352,11 @@ static void X11Toolkit_SettingsNotify(const char *name, XSettingsAction action, } /* set scale vars */ - window->scale = X11Toolkit_GetUIScale(window->xsettings, window->display); + window->scale = X11_GetGlobalContentScale(window->display, window->xsettings); window->iscale = (int)SDL_ceilf(window->scale); + if (window->scale < 1) { + window->scale = 1; + } if (SDL_roundf(window->scale) == window->scale) { window->scale = 0; } @@ -728,7 +616,10 @@ SDL_ToolkitWindowX11 *X11Toolkit_CreateWindowStruct(SDL_Window *parent, SDL_Tool window->xsettings_first_time = true; window->xsettings = xsettings_client_new(window->display, DefaultScreen(window->display), X11Toolkit_SettingsNotify, NULL, window); window->xsettings_first_time = false; - window->scale = X11Toolkit_GetUIScale(window->xsettings, window->display); + window->scale = X11_GetGlobalContentScale(window->display, window->xsettings); + if (window->scale < 1) { + window->scale = 1; + } window->iscale = (int)SDL_ceilf(window->scale); if (SDL_roundf(window->scale) == window->scale) { window->scale = 0;