Set content and UI scales to 1 if the retrieved value is smaller than 1 (#14193)

This commit is contained in:
eafton
2025-10-10 01:02:49 +03:00
committed by GitHub
parent d92079f2b7
commit ab76f040c4
5 changed files with 36 additions and 135 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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_

View File

@@ -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;