mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-02-17 09:04:07 +00:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user