I want to make my application, which is purely in X11, high DPI aware. In order to do this, I need a way to find out the system scale factor that is configured in the display settings. Is there any way to get this system scale factor from an X11 app without resorting to higher level APIs like GTK?
FWIW, I've checked the GTK sources to see how gdk_window_get_scale_factor()
does it and it seems to read an environment variable named GDK_SCALE
. This environment variable, however, isn't there on my system at all, even though I've set scaling to 1.75 on my 4K monitor.
So how can I programmatically retrieve the system scaling factor?
To answer my own question, I've now tried three approaches:
DisplayWidth/Height
and DisplayWidthMM/HeightMM
xdpyinfo
outputNeither returns the correct DPI. Instead, the Xft.dpi
Xresource seems to be the key to this problem. Xft.dpi
always seems to carry the correct DPI so we can just read it to get the system scale factor.
Here's some source taken from here:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
double _glfwPlatformGetMonitorDPI(_GLFWmonitor* monitor)
{
char *resourceString = XResourceManagerString(_glfw.x11.display);
XrmDatabase db;
XrmValue value;
char *type = NULL;
double dpi = 0.0;
XrmInitialize(); /* Need to initialize the DB before calling Xrm* functions */
db = XrmGetStringDatabase(resourceString);
if (resourceString) {
printf("Entire DB:\n%s\n", resourceString);
if (XrmGetResource(db, "Xft.dpi", "String", &type, &value) == True) {
if (value.addr) {
dpi = atof(value.addr);
}
}
}
printf("DPI: %f\n", dpi);
return dpi;
}
This does the trick for me.