Browse Source

Added SDL_HINT_VIDEO_X11_SCALING_FACTOR to allow overriding the content scale on X11 (thanks Andres!)

Sam Lantinga 1 year ago
parent
commit
4e81b4e8de
2 changed files with 36 additions and 16 deletions
  1. 7 0
      include/SDL3/SDL_hints.h
  2. 29 16
      src/video/x11/SDL_x11modes.c

+ 7 - 0
include/SDL3/SDL_hints.h

@@ -1938,6 +1938,13 @@ extern "C" {
  */
 #define SDL_HINT_VIDEO_X11_WINDOW_VISUALID      "SDL_VIDEO_X11_WINDOW_VISUALID"
 
+/**
+ *  \brief  A variable forcing the scaling factor for X11 windows
+ *
+ *  This variable can be set to a floating point value in the range 1.0-10.0f
+ */
+#define SDL_HINT_VIDEO_X11_SCALING_FACTOR      "SDL_VIDEO_X11_SCALING_FACTOR"
+
 /**
  *  \brief  A variable controlling whether the X11 XRandR extension should be used.
  *

+ 29 - 16
src/video/x11/SDL_x11modes.c

@@ -164,29 +164,42 @@ static float GetGlobalContentScale(SDL_VideoDevice *_this)
     static double scale_factor = 0.0;
 
     if (scale_factor <= 0.0) {
-        /* First try the settings portal via D-Bus for the text scaling factor (aka 'Global Scale' on KDE) */
+
+        /* 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;
+            }
+        }
+
+        /* Next try the settings portal via D-Bus for the text scaling factor (aka 'Global Scale' on KDE) */
 #ifdef SDL_USE_LIBDBUS
-        DBusMessage *reply;
-        SDL_DBusContext *dbus = SDL_DBus_GetContext();
-
-        if (dbus) {
-            if ((reply = ReadDBusSetting(dbus, SCALE_FACTOR_KEY))) {
-                if (ParseDBusReply(dbus, reply, DBUS_TYPE_DOUBLE, &scale_factor)) {
-                    /* If the setting exists, register a listener for scale changes. */
-                    dbus->bus_add_match(dbus->session_conn,
-                                        "type='signal', interface='"SCALE_FACTOR_INTERFACE"',"
-                                        "member='"SCALE_FACTOR_SIGNAL_NAME"', arg0='"SCALE_FACTOR_NAMESPACE"',"
-                                        "arg1='"SCALE_FACTOR_KEY"'", NULL);
-                    dbus->connection_add_filter(dbus->session_conn, &DBus_MessageFilter, &scale_factor, NULL);
-                    dbus->connection_flush(dbus->session_conn);
+        if (scale_factor <= 0.0)
+        {
+            DBusMessage *reply;
+            SDL_DBusContext *dbus = SDL_DBus_GetContext();
+
+            if (dbus) {
+                if ((reply = ReadDBusSetting(dbus, SCALE_FACTOR_KEY))) {
+                    if (ParseDBusReply(dbus, reply, DBUS_TYPE_DOUBLE, &scale_factor)) {
+                        /* If the setting exists, register a listener for scale changes. */
+                        dbus->bus_add_match(dbus->session_conn,
+                                            "type='signal', interface='"SCALE_FACTOR_INTERFACE"',"
+                                            "member='"SCALE_FACTOR_SIGNAL_NAME"', arg0='"SCALE_FACTOR_NAMESPACE"',"
+                                            "arg1='"SCALE_FACTOR_KEY"'", NULL);
+                        dbus->connection_add_filter(dbus->session_conn, &DBus_MessageFilter, &scale_factor, NULL);
+                        dbus->connection_flush(dbus->session_conn);
+                    }
+                    dbus->message_unref(reply);
                 }
-                dbus->message_unref(reply);
             }
         }
+#endif
 
         /* If that failed, try "Xft.dpi" from the XResourcesDatabase... */
         if (scale_factor <= 0.0)
-#endif
         {
             SDL_VideoData *data = _this->driverdata;
             Display *display = data->display;