Hacker News new | ask | show | jobs
by bitwize 979 days ago
X can easily support per-display DPI -- clients just have to eschew the legacy global DPI setting. The Xrandr extension knows the dimensions of each display in both pixels and millimeters from its EDID. Clients interested in making adjustments based on per-display DPI could simply use those values obtained from Xrandr. These values can be wrong, of course -- monitors have been known to lie in their EDID reports -- but they'd be wrong in Wayland too.

Of course, no one actually wants to do this work because there is a deep-seated intent to salt the earth where X once stood.

4 comments

The way multihead works in modern XOrg is basically a hack to enable seamless dragging of windows across physical display boundaries.

Once upon a time you'd do multihead on X with discrete screens and your display environment variable would be something like DISPLAY=:0.0 vs. DISPLAY=:0.1 where the last digit after the dot was the screen number. But your X client would then be confined to that screen. In this old manner you could probably have per-screen DPI stuff work somewhat, but you wouldn't be moving windows across physical monitors like we take for granted today.

Having your X clients connect to DISPLAY=:0 and somewhere behind the scenes that X server is putting its windows across physical displays or moving from one to the other seamlessly is basically Magic (look up XINERAMA) that the protocol is largely ignorant of, so the DPI differences among those physical displays are pretty invisible to the random X client.

IDK if ability to drag a window between screens is something more important than properly supporting different DPIs; but that might be a decent level of ignorance on my part
Eh, I lived with the limitation back in the XFree86 4.0 / beta multihead support days on an array of Matrox Millenium PCI cards.

While it technically works, you quickly discover the importance of being able to organize windows to different physical displays after the programs are already running / the windows have been created.

Requiring exiting and relaunching things to migrate them to different physical screens gets old fast.

The best article I have found about mixed dpi on x11 is.

http://wok.oblomov.eu/tecnologia/mixed-dpi-x11/

That article is horrible. What it describes is yet another hack where clients attempt to guess the DPI and then rescale themselves, and the server and compositor know nothing about DPI. That method only exacerbates the problems where clients that don't support scaling are going to be scaled wrong on every screen. Compare this to Wayland where the compositor itself knows the scale of every window and does all the scaling.
Which is a fair assessment, And I think I agree with you. however there is a bit of irony around the whole situation.

The article reaches the conclusion that the best way to handle the situation is for the display server to provide the dpi primitives and let the client figure out how best to draw to that dpi. But acknowledges that there is a hack where you can make the server present a standard scaled dpi, but the drawing will then be bad. And there is this new-fangled thing called wayland where all it can do is the hack.

The irony is that wayland is infamous for usually making the clients do the work(I am thinking window managers) and X for providing a standard method. Nether of which is true, but it made me chuckle.

xrandr is not sufficient for this. One needs a way for users to configure the per monitor DPI. And have the configuration available to X clients. Currently the only cross DE mechanism for this is Xft.dpi and its global, not per monitor.
>Xft.dpi and its global, not per monitor.

It's per screen, though ; you can have different Xresources on different screens bound to different monitors, I'm running such configuration just fine. Actually, since most of the software I'm using is GTK-based, my per-monitor DPI configuration tool(s) are a pair of xsettingsd running with different DISPLAY variables, and having different Xft/DPI values (and a few other tweaks, like different font rendering options). I'm running two openbox instances , xfce4-panel and tint2 , and two picom instances to properly support client side decorations. And I'm trying to scrape some time to patch xfwm4 and xfce4-panel to support per-screen processes for both . This way I'm driving 24" 4K as my primary display, for coding/browsing/etc, and 24" 2K as a sidekick for monitoring/documentation/spotify/etc

My .xsession:

  xrdb -screen -display :0.0 -merge .Xresources-0.0
  xrdb -screen -display :0.1 -merge .Xresources-0.1
  nohup /usr/lib64/xfce4/xfconf/xfconfd &
  export FREETYPE_PROPERTIES="cff:no-stem-darkening=0 autofitter:no-stem-darkening=0 cff:darkening-parameters=500,500,2000,450,3300,450,4600,200" 
  export DISPLAY=:0.0
  export GDK_SCALE=2
  export GDK_DPI_SCALE=0.5
  export QT_AUTO_SCREEN_SCALE_FACTOR=0
  export QT_SCREEN_SCALE_FACTORS=2

  nohup xsettingsd -c ~/.xsettingsd-0.0 -s 0 &
  nohup openbox --config-file ~/.config/openbox/rc-0.0.xml &
  ~/Apps/Picom/picom --vsync  --use-ewmh-active-win  --no-frame-pacing --backend glx -b
  nohup xfce4-panel --display=:0.0 &
  nohup /usr/lib64/xfce4/notifyd/xfce4-notifyd &

  export FREETYPE_PROPERTIES="cff:no-stem-darkening=0 autofitter:no-stem-darkening=0" 
  export DISPLAY=:0.1
  unset GDK_SCALE
  unset GDK_DPI_SCALE
  unset QT_SCREEN_SCALE_FACTORS
  nohup xsettingsd -c ~/.xsettingsd-0.1 -s 1 &
  nohup openbox --config-file ~/.config/openbox/rc-0.1.xml &
  ~/Apps/Picom/picom --vsync  --use-ewmh-active-win  --no-frame-pacing --backend glx -b
  nohup tint2 &
  wait
If this works for you, cool. But this is... not good in any way, and it's still not going to work for clients that use a different toolkit or text renderer than the ones you've configured. I hope you can see how it's unacceptable for an average user to have to mess around with this many random commands and environment variables just to get scaling working.
xrandr is perfectly sufficient for this, although GTK for whatever reason chooses to break it (not just not implement it; proactively break it). Xcb picks it up just fine, as does Qt. I'm pretty sure Fltk does now too though I haven't tried it in a while.
No, xrandr isn't sufficient. It still doesn't have scaling information, only size information. Changing the reported physical size of the monitor is a bad idea as it can break other things.
OFFS this is the most ridiculous reaction ever.

Reporting the physical size of the monitor is the right answer. Wayland is simply wrong here.

No. Even the X.org developers disagree with you here. Messing with the DPI will cause lots of clients to break even further. See this merge request for more info on this: https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests...

X11 simply isn't built to do this. If you want this to work, then the last 35 years of clients don't do the right thing and still would need to be changed to use a new extension that behaves more like Wayland does it.

And yet, it works better than in Wayland.
> One needs a way for users to configure the per monitor DPI.

xrandr --setmonitor has entered the chat

Simpler you can just scale lower dpi clients down from a higher resolution. Applications think every screen has the same DPI and draw accordingly. X scales such displays to the correct physical size.