x11: Expose the text/global scaling factor as the display content scale
Expose the text scaling factor (aka the global scale factor on KDE) as the display content scale value so applications can scale themselves as necessary. If D-Bus is unavailable or retrieving the setting fails, fall back to trying the legacy GDK_SCALE envvar before reverting to the default 1.0 value.main
parent
87186a893c
commit
32ab1183c7
|
@ -39,6 +39,91 @@
|
|||
*/
|
||||
/* #define XRANDR_DISABLED_BY_DEFAULT */
|
||||
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
|
||||
static DBusMessage *ReadDBusSetting(SDL_DBusContext *dbus, const char *key)
|
||||
{
|
||||
static const char *iface = "org.gnome.desktop.interface";
|
||||
|
||||
DBusMessage *reply = NULL;
|
||||
DBusMessage *msg = dbus->message_new_method_call("org.freedesktop.portal.Desktop", /* Node */
|
||||
"/org/freedesktop/portal/desktop", /* Path */
|
||||
"org.freedesktop.portal.Settings", /* Interface */
|
||||
"Read"); /* Method */
|
||||
|
||||
if (msg) {
|
||||
if (dbus->message_append_args(msg, DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID)) {
|
||||
reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, msg, DBUS_TIMEOUT_USE_DEFAULT, NULL);
|
||||
}
|
||||
dbus->message_unref(msg);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static SDL_bool ParseDBusReply(SDL_DBusContext *dbus, DBusMessage *reply, int type, void *value)
|
||||
{
|
||||
DBusMessageIter iter[3];
|
||||
|
||||
dbus->message_iter_init(reply, &iter[0]);
|
||||
if (dbus->message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
dbus->message_iter_recurse(&iter[0], &iter[1]);
|
||||
if (dbus->message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
dbus->message_iter_recurse(&iter[1], &iter[2]);
|
||||
if (dbus->message_iter_get_arg_type(&iter[2]) != type) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
dbus->message_iter_get_basic(&iter[2], value);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static float GetGlobalContentScale()
|
||||
{
|
||||
static const char *text_scaling_factor = "text-scaling-factor";
|
||||
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) */
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
DBusMessage *reply;
|
||||
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
||||
|
||||
if (dbus) {
|
||||
if ((reply = ReadDBusSetting(dbus, text_scaling_factor))) {
|
||||
ParseDBusReply(dbus, reply, DBUS_TYPE_DOUBLE, &scale_factor);
|
||||
dbus->message_unref(reply);
|
||||
}
|
||||
}
|
||||
|
||||
/* If that failed, try the GDK_SCALE envvar... */
|
||||
if (scale_factor <= 0.0)
|
||||
#endif
|
||||
{
|
||||
const char *scale_str = SDL_getenv("GDK_SCALE");
|
||||
if (scale_str) {
|
||||
scale_factor = SDL_atoi(scale_str);
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing or a bad value, just fall back to 1.0 */
|
||||
if (scale_factor <= 0.0) {
|
||||
scale_factor = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return scale_factor;
|
||||
}
|
||||
|
||||
static int get_visualinfo(Display *display, int screen, XVisualInfo *vinfo)
|
||||
{
|
||||
const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
|
||||
|
@ -384,6 +469,7 @@ static int X11_AddXRandRDisplay(SDL_VideoDevice *_this, Display *dpy, int screen
|
|||
display.name = display_name;
|
||||
}
|
||||
display.desktop_mode = mode;
|
||||
display.content_scale = GetGlobalContentScale();
|
||||
display.driverdata = displaydata;
|
||||
if (SDL_AddVideoDisplay(&display, send_event) == 0) {
|
||||
return -1;
|
||||
|
@ -591,6 +677,7 @@ static int X11_InitModes_StdXlib(SDL_VideoDevice *_this)
|
|||
SDL_zero(display);
|
||||
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.content_scale = GetGlobalContentScale();
|
||||
display.driverdata = displaydata;
|
||||
if (SDL_AddVideoDisplay(&display, SDL_TRUE) == 0) {
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue