HiDPI

Monday, Feb 11, 2019 11:15 pm
William Barnes

My Matebook X Pro has a 13″ 3000×2000 display at 259ppi. It’s pretty sharp. Gnome (via Ubuntu 18.04) worked out of the box. I hear Plasma also works well out of the box but I haven’t tried it.

Getting HiDPI support with i3

Unlike Gnome, i3 has no built-in support for HiDPI displays. However, with a few tweaks, it works just fine. I’ll go over a few of the options I’ve experimented with. If you want the short answer, skip to the section on Xft. Quite a lot of this is covered at the Arch Wiki. I’ll be using my own DPI settings as an example so modify as needed.

The hard way: modifying xorg.conf

Xorg is the obvious place to start since it controls your display. There are a few ways to affect DPI in the short term. One method (useful for the Manjaro i3 install CD) is to type xrandr --output eDP1 --scale 2x2. You’ll get a usable but slightly fuzzy display. You can also set the DPI directly with xrandr --dpi 259 although your mileage may vary (it doesn’t seem to work if you’ve set the DPI by any other method).

To persist the settings you could put a call to xrandr in your .profile, but saving the values in xorg.conf is probably the way to go. You’ll need to either edit /etc/X11/xorg.conf or add a config file to /etc/X11/xorg.conf.d/. You can use one of two methods to tell xorg your DPI:

Section "Monitor"
Identifier "<default monitor>"
# To tell it your definitions and let X figure out the DPI
DisplaySize 294 196
# To just tell it the DPI
Option "DPI" "259 x 259"
# Only use one of the two above options
EndSection

This method will scale i3 and any plain X applications like URxvt. However, if you use some GTK applications like Libre Office or Chrome, those will be unaffected. You’ll need to tell GTK about your resolution.

Scaling GTK applications

There are a few ways to scale GDK applications. Ignore any advice about using gsettings to alter the text-scaling-factor. It has no noticeable effect on programs rendered outside of the Gnome DE. Testing it under Gnome suggests it affects the window decorations in Gnome but, since you’re using another window manager, it doesn’t do anything here.

There are two environment variables that you can use to scale GTK applications. GDK_SCALE (yes, that’s a “D”) will allow you to multiply the size of GTK applications by any integer value. GDK_DPI_SCALE will allow you to multiply the size by any fractional value. Why do both exist? According to the Gnome documentation, GDK_SCALE appears to be intended for your usual display scaling and GDK_DPI_SCALE exists as a workaround for people using non-HiDPI aware applications: it allows the user to double the system font size to make those applications readable and then halve the text size of GTK apps to bring them back to size.

You can use GDK_SCALEon it’s own to double or triple the size of GTK apps, but that’s probably not what you want. You can use GDK_DPI_SCALE on it’s own to set any fractional value. It works, but it’s not perfect. My guess is that the latter method increases the font-size and the UI scales to compensate. This leads to text that is slightly too large for the UI. Instead, what you can do is scale up with GDK_SCALE and then scale down the text with GDK_DPI_SCALE. Notice in the following photo how the UI is cramped when using GDK_DPI_SCALE on it’s own:

GDK_DPI_SCALE=1.5 vs GDK_SCALE=2 & GDK_DPI_SCALE=0.75

Scaling Google Chrome

Google Chrome isn’t affected by the GDK environment variables. However, it has a runtime parameter to force scaling: google-chrome-stable --high-dpi-support=1 --force-device-scale-factor=2

The easy way: Xresources and Xft

Forget everything above. Add the following line to the file ~/.Xresources: Xft.dpi: 180

Restart X and you’re done.

This will scale i3, GTK apps, and Chrome. You’ll have to manually increase font sizes in a few applications that don’t obey this setting like URxvt. You should definitely add GDK_SCALE=2 to your .profile and cancel it out with GDK_DPI_SCALE=0.5. This will fix the spacing issues seen in the screenshot above.

What I learned

I think DPI is solving the wrong problem. This value should be accurately reported but it shouldn’t be determining the size of UI elements and content except in very limited circumstances where absolute size is critical (e.g., word processing). Outside of those use cases, what people care about is apparent size. And that is heavily affected by how close you sit to your screen. I don’t want a website to appear the same absolute size on my laptop and my 24″ 96 DPI screen. I want it to be a little bit smaller but for it to appear a similar size after I move closer to the screen.

In the end, this means setting an inaccurate (too low) DPI on the HiDPI screen. This tricks the system into drawing elements slightly smaller and preserves the apparent size across systems. It simplifies the sharing of configuration files because even though a 12pt font will be different sizes on each computer, it should appear to be the same size. And that’s all that matters.