2626#include "SDL_x11video.h"
2727#include "SDL_x11settings.h"
2828
29+ #include "core/unix/SDL_gtk.h"
30+
2931#define SDL_XSETTINGS_GDK_WINDOW_SCALING_FACTOR "Gdk/WindowScalingFactor"
3032#define SDL_XSETTINGS_XFT_DPI "Xft/DPI"
3133
@@ -65,13 +67,53 @@ static void X11_XsettingsNotify(const char *name, XSettingsAction action, XSetti
6567 }
6668}
6769
70+ static void OnGtkXftDpi (GtkSettings * settings , GParamSpec * pspec , gpointer ptr )
71+ {
72+ 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+ }
89+ }
90+
6891void X11_InitXsettings (SDL_VideoDevice * _this )
6992{
7093 SDL_VideoData * data = _this -> internal ;
7194 SDLX11_SettingsData * xsettings_data = & data -> xsettings_data ;
7295
73- xsettings_data -> xsettings = xsettings_client_new (data -> display ,
74- DefaultScreen (data -> display ), X11_XsettingsNotify , NULL , _this );
96+ GtkSettings * gtksettings = NULL ;
97+ guint xft_dpi_signal_handler_id = 0 ;
98+
99+ SDL_GtkContext * gtk = SDL_Gtk_EnterContext ();
100+ if (gtk ) {
101+ // Prefer to listen for DPI changes from gtk. In XWayland this is necessary as XSettings
102+ // are not updated dynamically.
103+ gtksettings = gtk -> gtk .settings_get_default ();
104+ if (gtksettings ) {
105+ xft_dpi_signal_handler_id = gtk -> g .signal_connect (gtksettings , "notify::gtk-xft-dpi" , & OnGtkXftDpi , _this );
106+ }
107+ SDL_Gtk_ExitContext (gtk );
108+ }
109+
110+ if (gtksettings && xft_dpi_signal_handler_id ) {
111+ xsettings_data -> gtksettings = gtksettings ;
112+ 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 );
116+ }
75117
76118}
77119
@@ -82,8 +124,17 @@ void X11_QuitXsettings(SDL_VideoDevice *_this)
82124
83125 if (xsettings_data -> xsettings ) {
84126 xsettings_client_destroy (xsettings_data -> xsettings );
85- xsettings_data -> xsettings = NULL ;
86127 }
128+
129+ SDL_GtkContext * gtk = SDL_Gtk_EnterContext ();
130+ if (gtk ) {
131+ if (xsettings_data -> gtksettings && xsettings_data -> xft_dpi_signal_handler_id ) {
132+ gtk -> g .signal_handler_disconnect (xsettings_data -> gtksettings , xsettings_data -> xft_dpi_signal_handler_id );
133+ }
134+ SDL_Gtk_ExitContext (gtk );
135+ }
136+
137+ SDL_zero (xsettings_data );
87138}
88139
89140void X11_HandleXsettings (SDL_VideoDevice * _this , const XEvent * xevent )
0 commit comments