2
0
Эх сурвалжийг харах

x11: Fix regression reading GNOME content scale

- Removed gtk-xft-dpi read from GetGlobalContentScale. Xrm either returns either the same value as gtk-xft-dpi or the integer
  scale value in cases where gtk-xft-dpi is 1.

- Refactor SDL_x11settings handlers to defer to GetGlobalContentScale

- GetGlobalContentScale is now exported and the XSettings and Gtk signal handlers now use it for consistency. This involves
  a bit of extra work reading from Xrm rather than the setting notification but ensures consistent handling based on signal
  origin and hints enabled.

- Hook both gtk-xft-dpi in SDL_x11settings. This should generally result in only one being called based on which is updated.
  Since both signal handlers defer to X11_GetGlobalContentScale this will cause the same content scale to be applied multiple
  times. The gtk-xft-dpi signal is now only used to trigger content scale updates when the XSettings notification does not occur.
Sam Lantinga 1 сар өмнө
parent
commit
293b8b9fd6

+ 3 - 17
src/video/x11/SDL_x11modes.c

@@ -48,7 +48,7 @@
  */
 // #define XRANDR_DISABLED_BY_DEFAULT
 
-static float GetGlobalContentScale(SDL_VideoDevice *_this)
+float X11_GetGlobalContentScale(SDL_VideoDevice *_this)
 {
     static double scale_factor = 0.0;
 
@@ -63,20 +63,6 @@ static float GetGlobalContentScale(SDL_VideoDevice *_this)
             }
         }
 
-        // If that failed, try "Xft.dpi" from GTK if available. On XWayland this
-        // will retrieve the current scale factor which is not updated dynamically
-        // in the Xrm database.
-        SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
-        if (gtk) {
-            GtkSettings *gtksettings = gtk->gtk.settings_get_default();
-            if (gtksettings) {
-                int dpi = 0;
-                gtk->g.object_get(gtksettings, "gtk-xft-dpi", &dpi, NULL);
-                scale_factor = dpi / 1024.0 / 96.0;
-            }
-            SDL_Gtk_ExitContext(gtk);
-        }
-
         // If that failed, try "Xft.dpi" from the XResourcesDatabase...
         if (scale_factor <= 0.0)
         {
@@ -505,7 +491,7 @@ static bool X11_FillXRandRDisplayInfo(SDL_VideoDevice *_this, Display *dpy, int
         display->name = display_name;
     }
     display->desktop_mode = mode;
-    display->content_scale = GetGlobalContentScale(_this);
+    display->content_scale = X11_GetGlobalContentScale(_this);
     display->internal = displaydata;
 
     return true;
@@ -875,7 +861,7 @@ static bool X11_InitModes_StdXlib(SDL_VideoDevice *_this)
     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 = GetGlobalContentScale(_this);
+    display.content_scale = X11_GetGlobalContentScale(_this);
     if (SDL_AddVideoDisplay(&display, true) == 0) {
         return false;
     }

+ 2 - 0
src/video/x11/SDL_x11modes.h

@@ -62,6 +62,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);
+
 #ifdef SDL_VIDEO_DRIVER_X11_XRANDR
 extern void X11_HandleXRandREvent(SDL_VideoDevice *_this, const XEvent *xevent);
 #endif

+ 12 - 48
src/video/x11/SDL_x11settings.c

@@ -31,61 +31,26 @@
 #define SDL_XSETTINGS_GDK_WINDOW_SCALING_FACTOR "Gdk/WindowScalingFactor"
 #define SDL_XSETTINGS_XFT_DPI "Xft/DPI"
 
-static void X11_XsettingsNotify(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
+static void UpdateContentScale(SDL_VideoDevice *_this)
 {
-    SDL_VideoDevice *_this = data;
-    float scale_factor = 1.0;
-    int i;
-
-    if (SDL_strcmp(name, SDL_XSETTINGS_GDK_WINDOW_SCALING_FACTOR) != 0 ||
-        SDL_strcmp(name, SDL_XSETTINGS_XFT_DPI) != 0) {
-        return;
-    }
-
-    if (setting->type != XSETTINGS_TYPE_INT) {
-        return;
-    }
-
-    switch (action) {
-    case XSETTINGS_ACTION_NEW:
-        SDL_FALLTHROUGH;
-    case XSETTINGS_ACTION_CHANGED:
-        scale_factor = setting->data.v_int;
-        if (SDL_strcmp(name, SDL_XSETTINGS_XFT_DPI) == 0) {
-            scale_factor = scale_factor / 1024.0f / 96.0f;
-        }
-        break;
-    case XSETTINGS_ACTION_DELETED:
-        scale_factor = 1.0;
-        break;
-    }
-
     if (_this) {
-        for (i = 0; i < _this->num_displays; ++i) {
+        float scale_factor = X11_GetGlobalContentScale(_this);
+        for (int i = 0; i < _this->num_displays; ++i) {
             SDL_SetDisplayContentScale(_this->displays[i], scale_factor);
         }
     }
 }
 
+static void X11_XsettingsNotify(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
+{
+    SDL_VideoDevice *_this = data;
+    UpdateContentScale(_this);
+}
+
 static void OnGtkXftDpi(GtkSettings *settings, GParamSpec *pspec, gpointer ptr)
 {
     SDL_VideoDevice *_this = (SDL_VideoDevice *)ptr;
-
-    SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
-    if (gtk) {
-        int dpi = 0;
-        gtk->g.object_get(settings, "gtk-xft-dpi", &dpi, NULL);
-        
-        if (dpi != 0) {
-            float scale_factor = dpi / 1024.f / 96.f;
-
-            for (int i = 0; i < _this->num_displays; ++i) {
-                SDL_VideoDisplay *display = _this->displays[i];
-                SDL_SetDisplayContentScale(display, scale_factor);
-            }
-        }
-        SDL_Gtk_ExitContext(gtk);
-    }
+    UpdateContentScale(_this);
 }
 
 void X11_InitXsettings(SDL_VideoDevice *_this)
@@ -110,11 +75,10 @@ void X11_InitXsettings(SDL_VideoDevice *_this)
     if (gtksettings && xft_dpi_signal_handler_id) {
         xsettings_data->gtksettings = gtksettings;
         xsettings_data->xft_dpi_signal_handler_id = xft_dpi_signal_handler_id;
-    } else {
-        xsettings_data->xsettings = xsettings_client_new(data->display,
-            DefaultScreen(data->display), X11_XsettingsNotify, NULL, _this);
     }
 
+    xsettings_data->xsettings = xsettings_client_new(data->display,
+        DefaultScreen(data->display), X11_XsettingsNotify, NULL, _this);
 }
 
 void X11_QuitXsettings(SDL_VideoDevice *_this)