Browse Source

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

eafton 16 hours ago
parent
commit
ab76f040c4

+ 14 - 10
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;

+ 4 - 1
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);

+ 8 - 7
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

+ 2 - 0
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_

+ 8 - 117
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;