HiDPI in i3
I am using i3 as a Window Manager. I love the feeling of being able to control everything via keyboard. Its tiling nature and easy access to different workspaces is what makes me very comfortable in it. I started using it in February 2021 and enjoyed it since.
When starting remote work at Splitgraph, I got 2 Acer Nitro VG280K 28 inch 4k monitors. They were quite an upgrade from my previous 22 inch 1080p monitors.
Immediately after connecting them to my laptop and using
xrandr
to initialize them
$ xrandr --output HDMI-0 --auto \
--output DP-0 --auto --right-of HDMI-0
$ xrandr
Screen 0: minimum 8 x 8, current 7680 x 2160, maximum 32767 x 32767
DP-0 connected 3840x2160+3840+0 (normal left inverted right x axis y axis) 620mm x 340mm
3840x2160 60.00*+ 59.94 50.00 29.97 25.00 23.98
2560x1440 59.95
1920x1080 60.00 59.94 50.00
1680x1050 59.95
1440x900 59.89
1280x1024 75.02 60.02
1280x960 60.00
1280x800 59.81
1280x720 60.00 59.94 50.00
1152x864 75.00
1024x768 75.03 70.07 60.00
800x600 75.00 72.19 60.32 56.25
720x576 50.00
720x480 59.94
640x480 75.00 72.81 59.94 59.93
DP-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 disconnected (normal left inverted right x axis y axis)
HDMI-0 connected primary 3840x2160+0+0 (normal left inverted right x axis y axis) 621mm x 341mm
3840x2160 60.00*+ 59.94 50.00 29.97 25.00 23.98
2560x1440 59.95
1920x1080 60.00 59.94 50.00
1680x1050 59.95
1440x900 59.89
1280x1024 75.02 60.02
1280x960 60.00
1280x800 59.81
1280x720 60.00 59.94 50.00
1152x864 75.00
1024x768 75.03 70.07 60.00
800x600 75.00 72.19 60.32 56.25
720x576 50.00
720x480 59.94
640x480 75.00 72.81 59.94 59.93
DP-4 disconnected (normal left inverted right x axis y axis)
I noticed a problem. The text was too small!
As outlined in this HackerNews comment, text rendered in a 4k resolution (3840x2160) is hard to read below 43 inches without scaling. I can confirm that - the text was way too small for me at a distance I was previously comfortable.
I switched to Windows and tried using it there. Windows immediately scaled up the resolution by 150% but it was still using 4k. This made the text readable, the interface large enough to use comfortably, and any content like videos on YouTube were shown in 4k. The sweet spot.
I tried to do the same on my Ubuntu with i3. I failed. I was too much of an Xorg/i3 newbie to follow all the instructions. All in all, I settled on using 2560x1440 as my resolution on both monitors. It made the text a bit blurry and the videos were running in 1440p max (no 4k for me), but at least it was easy to set up and it didn't require any custom scripts.
xrandr --output HDMI-0 --mode 2560x1440 \
--output DP-0 --mode 2560x1440 --right-of HDMI-0
After 10 months of running my monitors in 1440p, I started tinkering around with my i3/Xorg config to try to get HiDPI to work.
Scale it up, then scale it down
I wanted to use 4k but scale the interface so it it has the readability of 1440p.
As I learned, the way to get HiDPI work in Xorg is as follows:
-
Set
Xft.dpi: 192
in~/.Xresources
192 means 200% scaling.
This will make the interface twice as large.
Starting i3 again after this step made the interface on my monitors the size of 1080p without scaling.
-
Use
--scale
inxrandr
to change the resolution of the monitors.The value of
scale
needs to follow this equation:monitor_resolution = 3840 wanted_resolution = 2560 dpi_scale = 2 # wanted_resolution * dpi_scale = monitor_resolution * xrandr_scale xrandr_scale = wanted_resolution * dpi_scale / monitor_resolution xrandr_scale = 2560 * 2 / 3840 xrandr_scale = 5120 / 3840 xrandr_scale = 1.3333333333333
This way I could initialize my monitor with
xrandr --output HDMI-0 --auto --scale 1.33333333333x1.33333333333
and, horray, it works as expected. The text is crisp, but the resolution is 4k. In fact, the actual resolution that the graphics card has to render is even greater than 4k.
$ xrandr # ... HDMI-0 connected primary 5120x2880+0+0 (normal left inverted right x axis y axis) 621mm x 341mm 3840x2160 60.00*+ 59.94 50.00 29.97 25.00 23.98 # ...
-
Set
--panning
inxrandr
to get the monitors side-by-side.Adding
--scale
to my second output and using--right-of
inxrandr
caused the screen to overlap - the second displayed a part of the first monitor's screen.I used the
--panning
option to tellxrandr
precisely the range of pixels that I want each monitor show.xrandr --output HDMI-0 --auto --scale 1.33333333333x1.33333333333 \ --output DP-0 --auto --scale 1.33333333333x1.33333333333 \ --panning 5120x2880+5120+0
The
+5120+0
tellsxrandr
that myDP-0
(the right monitor) should be transated 5120px to the right. Thus, my first monitor renders horizontally pixels 0 - 5120, and my second monitor renders horizontally pixels 5120 - 10240.
I created a script to run these operations. I run that script each time i3 starts and I need to initialize the monitors.
Other DPI-related changes
Most applications render well after just setting Xft.dpi
. There were a couple
of places in my dotfiles that I had to change the font size, because it did not
scale with Xft.dpi
:
- i3 font size
- i3 bar font size
- rofi font size
- GDK applications DPI (see GDK 3 section in the HiDPI guide)
Xcursor.size
- dunst font size
Regular DPI outside my home
I did not want to keep using HiDPI when I did not need it. This would negatively impact battery life and generate excess heat by the graphics card, because it would have to render 4 times as many pixels while offering no visual benefits.
I opted to use gomplate to
dynamically generate the configuration that is dependent on DPI. I run
the script to generate the config files based on the DPI
before executing startx
.
This way I can easily switch between HiDPI and normal DPI.
Conclusion
HiDPI is supported when using i3. It requires more work to set up than in other operating systems and is less seamless. I did not find a way to dynamically change the scaling without exiting i3 and starting it again with updated settings.
All in all, the support for scaling it pretty good and after setting it up, I have not faced problems with it so far. Applications seems to work and scale well.