3 ms·
If anybody knows how to forcibly override the "pixels per mm" reported by a monitor, you will be my hero forever. Every solution I've found so far (including t
by KirillPanov 6y ago
If anybody knows how to forcibly override the "pixels per mm" reported by a monitor, you will be my hero forever.
Every solution I've found so far (including the QT/GTK environment variables for overriding DPI) ends up instead causing scaling during compositing, rather than getting the apps to rasterize their fonts at the correct size in the first place. The worst offenders are anything derived from Chromium (i.e. qutebrowser, who say the problem is a QtWebEngine bug that they can't fix).
I'm using sway, but almost all the Wayland compositors lack this override-the-monitor-reported-DPI functionality, because (for good reason) their philosophy is to securely multiplex the hardware, not abstract it away. They just pass through whatever values the monitor reports, to the client.
IMHO this does not make sense for physical pixel size, because it disregards the physical distance between the user's face and the pixels. What you really want to size your fonts based on is the number of arc-radians (or arc-degrees) per pixel, measured at the user's eyeball. In order to compute that you need to know both the physical pixel size (which can be queried from the device) and the physical eyeball-screen distance (which will need to be user-configurable).
- cycloptic 6y agoI don't know of any Wayland implementations that let you do that, it wouldn't be hard to hack in, but Wayland applications should not be using that information to decide scaling. They should be using the wl_output.scale. In X11, you can do it with xrandr --fbmm. Technically you can also set this information per-monitor but I don't think a command line option was ever added for it.
- KirillPanov 6y ago> In X11, you can do it with xrandr --fbmm Yeah, that's basically what I want, but for sway. > Wayland applications should not be using that information to decide scaling. They should be using the wl_output.scale. Maybe so, but the physical size is definitely exposed to the clients via the wayland protocol (see below). I'm pretty sure that the QT toolkit and Chromium both use the reported values. <event name="geometry"> <description summary="properties of the output"> The geometry event describes geometric properties of the output. The event is sent when binding to the output object and whenever any of the properties change. The physical size can be set to zero if it doesn't make sense for this output (e.g. for projectors or virtual outputs). </description> <arg name="x" type="int" /> <arg name="y" type="int" /> <arg name="physical_width" type="int" /> <arg name="physical_height" type="int" /> <arg name="subpixel" type="int" enum="subpixel" /> <arg name="make" type="string" /> <arg name="model" type="string" /> <arg name="transform" type="int" enum="transform" /> </event> I will probably end up hacking it into sway, like I've done with other things. It's just that the swaywm/libwlroots codebase is so utterly illegible. "wlroots is largely documented through comments in the headers. Read 'em." Yeah, those headers with no comments anywhere, egregious amounts of boilerplate code (because C), and naming conventions that take weeks to learn. Argh. I've spent entire days trying to figure out "how to I get a sway_foo pointer from a wlr_foo pointer". It's madness. There's so much typecasting going (with totally undocumented rules for when said typecasts are safe) on that you can't even use the compiler-visible types as a guide for these kinds of questions.
- cycloptic 6y agoIs there some reason you cannot just set the output scale? This almost certainly already does what you want. If you're talking about X11 applications running on XWayland, I think you can still change the properties there with xrandr.
- KirillPanov 6y agoI've definitely tried that and it has the wrong effect in a lot of cases. The worst is Chromium (via QtWebEngine, via qutebrowser), which seems to ignore things. No, I'm not using XWayland. I edited my comment above after you posted -- the Wayland protocol unfortunately does expose the screen size in millimeters to the client. I'm pretty sure Chromium and QT use this, which is why I need to lie to them. Another question: is there any sort of "Wayland socket proxy"? Like a stupid simple program that offers up a $WAYLAND_DISPLAY socket to a client, opens its own to a server, and then passes all results through unmodified? It would be really easy to hack a change like this into a proxy like that, but I can't seem to find one. Sort of surprising; the simplicity of the Wayland protocol makes it seem like such a thing should exist. Sort of like waypipe, but without the cross-network magic.
- cycloptic 6y agoQt applications are almost certainly using the output scale property, I've tried those recently. I haven't tested Chromium's wayland backend recently, but Chromium is ignoring those physical values: https://github.com/chromium/chromium/blob/99314be8152e688bafbbf9a615536bdbb289ea87/ui/ozone/platform/wayland/host/wayland_output.cc#L39 https://github.com/chromium/chromium/blob/99314be8152e688baf... Maybe your chromium is not using the Wayland backend correctly? If a Wayland application is using the physical values to determine scaling, instead of the output scale, that's a bug and you probably should consider reporting it. It's probably a mistake that the physical size information is there, it's unreliable as you have seen. Edit: Rather than messing around with proxies, if you want to do a quick test to confirm, you could simply hack wlroots here to send a constant value: https://github.com/swaywm/wlroots/blob/b3e76d667855c16e97a4de1658d786492fed1571/types/wlr_output.c#L25 https://github.com/swaywm/wlroots/blob/b3e76d667855c16e97a4d...
- derefr 6y ago> If anybody knows how to forcibly override the "pixels per mm" reported by a monitor, you will be my hero forever. The brute-force way to alter everything your monitor reports, is to dump its EDID data, patch it (there are programs for this, or you can resort to a hex editor and the EDID spec), and then tell your kernel to load that patched EDID in place of the real EDID when it recognizes your monitor. On Linux, that's apparently accomplished by plopping the patched EDID file into /lib/firmware: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/EDID/HOWTO.txt?id=be53bfdb8088e9d1924199cc1a96e113756b1075 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin... (I've never actually done this with Linux, but I've done it in macOS on a Hackintosh, because macOS frequently thinks televisions connected over HDMI should be fed YUV instead of sRGB. You can patch the EDID to force macOS to treat the TV as a monitor.)