Skip to content

Commit 293b8b9

Browse files
committed
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.
1 parent 7bb045c commit 293b8b9

File tree

3 files changed

+17
-65
lines changed

3 files changed

+17
-65
lines changed

src/video/x11/SDL_x11modes.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
*/
4949
// #define XRANDR_DISABLED_BY_DEFAULT
5050

51-
static float GetGlobalContentScale(SDL_VideoDevice *_this)
51+
float X11_GetGlobalContentScale(SDL_VideoDevice *_this)
5252
{
5353
static double scale_factor = 0.0;
5454

@@ -63,20 +63,6 @@ static float GetGlobalContentScale(SDL_VideoDevice *_this)
6363
}
6464
}
6565

66-
// If that failed, try "Xft.dpi" from GTK if available. On XWayland this
67-
// will retrieve the current scale factor which is not updated dynamically
68-
// in the Xrm database.
69-
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
70-
if (gtk) {
71-
GtkSettings *gtksettings = gtk->gtk.settings_get_default();
72-
if (gtksettings) {
73-
int dpi = 0;
74-
gtk->g.object_get(gtksettings, "gtk-xft-dpi", &dpi, NULL);
75-
scale_factor = dpi / 1024.0 / 96.0;
76-
}
77-
SDL_Gtk_ExitContext(gtk);
78-
}
79-
8066
// If that failed, try "Xft.dpi" from the XResourcesDatabase...
8167
if (scale_factor <= 0.0)
8268
{
@@ -505,7 +491,7 @@ static bool X11_FillXRandRDisplayInfo(SDL_VideoDevice *_this, Display *dpy, int
505491
display->name = display_name;
506492
}
507493
display->desktop_mode = mode;
508-
display->content_scale = GetGlobalContentScale(_this);
494+
display->content_scale = X11_GetGlobalContentScale(_this);
509495
display->internal = displaydata;
510496

511497
return true;
@@ -875,7 +861,7 @@ static bool X11_InitModes_StdXlib(SDL_VideoDevice *_this)
875861
display.name = (char *)"Generic X11 Display"; /* this is just copied and thrown away, it's safe to cast to char* here. */
876862
display.desktop_mode = mode;
877863
display.internal = displaydata;
878-
display.content_scale = GetGlobalContentScale(_this);
864+
display.content_scale = X11_GetGlobalContentScale(_this);
879865
if (SDL_AddVideoDisplay(&display, true) == 0) {
880866
return false;
881867
}

src/video/x11/SDL_x11modes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ extern SDL_PixelFormat X11_GetPixelFormatFromVisualInfo(Display *display, XVisua
6262
extern bool X11_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *sdl_display, SDL_Rect *rect);
6363
extern bool X11_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *sdl_display, SDL_Rect *rect);
6464

65+
extern float X11_GetGlobalContentScale(SDL_VideoDevice *_this);
66+
6567
#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
6668
extern void X11_HandleXRandREvent(SDL_VideoDevice *_this, const XEvent *xevent);
6769
#endif

src/video/x11/SDL_x11settings.c

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -31,61 +31,26 @@
3131
#define SDL_XSETTINGS_GDK_WINDOW_SCALING_FACTOR "Gdk/WindowScalingFactor"
3232
#define SDL_XSETTINGS_XFT_DPI "Xft/DPI"
3333

34-
static void X11_XsettingsNotify(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
34+
static void UpdateContentScale(SDL_VideoDevice *_this)
3535
{
36-
SDL_VideoDevice *_this = data;
37-
float scale_factor = 1.0;
38-
int i;
39-
40-
if (SDL_strcmp(name, SDL_XSETTINGS_GDK_WINDOW_SCALING_FACTOR) != 0 ||
41-
SDL_strcmp(name, SDL_XSETTINGS_XFT_DPI) != 0) {
42-
return;
43-
}
44-
45-
if (setting->type != XSETTINGS_TYPE_INT) {
46-
return;
47-
}
48-
49-
switch (action) {
50-
case XSETTINGS_ACTION_NEW:
51-
SDL_FALLTHROUGH;
52-
case XSETTINGS_ACTION_CHANGED:
53-
scale_factor = setting->data.v_int;
54-
if (SDL_strcmp(name, SDL_XSETTINGS_XFT_DPI) == 0) {
55-
scale_factor = scale_factor / 1024.0f / 96.0f;
56-
}
57-
break;
58-
case XSETTINGS_ACTION_DELETED:
59-
scale_factor = 1.0;
60-
break;
61-
}
62-
6336
if (_this) {
64-
for (i = 0; i < _this->num_displays; ++i) {
37+
float scale_factor = X11_GetGlobalContentScale(_this);
38+
for (int i = 0; i < _this->num_displays; ++i) {
6539
SDL_SetDisplayContentScale(_this->displays[i], scale_factor);
6640
}
6741
}
6842
}
6943

44+
static void X11_XsettingsNotify(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
45+
{
46+
SDL_VideoDevice *_this = data;
47+
UpdateContentScale(_this);
48+
}
49+
7050
static void OnGtkXftDpi(GtkSettings *settings, GParamSpec *pspec, gpointer ptr)
7151
{
7252
SDL_VideoDevice *_this = (SDL_VideoDevice *)ptr;
73-
74-
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
75-
if (gtk) {
76-
int dpi = 0;
77-
gtk->g.object_get(settings, "gtk-xft-dpi", &dpi, NULL);
78-
79-
if (dpi != 0) {
80-
float scale_factor = dpi / 1024.f / 96.f;
81-
82-
for (int i = 0; i < _this->num_displays; ++i) {
83-
SDL_VideoDisplay *display = _this->displays[i];
84-
SDL_SetDisplayContentScale(display, scale_factor);
85-
}
86-
}
87-
SDL_Gtk_ExitContext(gtk);
88-
}
53+
UpdateContentScale(_this);
8954
}
9055

9156
void X11_InitXsettings(SDL_VideoDevice *_this)
@@ -110,11 +75,10 @@ void X11_InitXsettings(SDL_VideoDevice *_this)
11075
if (gtksettings && xft_dpi_signal_handler_id) {
11176
xsettings_data->gtksettings = gtksettings;
11277
xsettings_data->xft_dpi_signal_handler_id = xft_dpi_signal_handler_id;
113-
} else {
114-
xsettings_data->xsettings = xsettings_client_new(data->display,
115-
DefaultScreen(data->display), X11_XsettingsNotify, NULL, _this);
11678
}
11779

80+
xsettings_data->xsettings = xsettings_client_new(data->display,
81+
DefaultScreen(data->display), X11_XsettingsNotify, NULL, _this);
11882
}
11983

12084
void X11_QuitXsettings(SDL_VideoDevice *_this)

0 commit comments

Comments
 (0)