xrandr – Multi Screen with Different DPI Configurations

Posted on 2020-07-03  5 Views

Multi-screen support on the Linux platform has not been as user-friendly as Windows and Mac. Recently, I have encountered trouble in configuring multiple screens with different DPI to achieve different scale scaling. This blog records the ideas and solutions to solve the problem for future reference. It's not perfect, but it doesn't affect use.

Environmental information

System environment:
Ubuntu 18.04 LTS (without Wayland enabled)
X.Org X Server 1.19.6
Gnome 3.28.2

Computer Model: Huawei MateBook 13 2018
Display Device: Screen 1: Built-in Monitor (CMN8201 Panel) 13 inch Resolution: 2160x1440 DPI 200 Screen 2: Philips 246E 23 inch Resolution:
DPI 96
notebook on the left, external monitor on the right.

# xrandr information
# The built-in display is eDP-1 and the external display is DP-1
Screen 0: minimum 320 x 200, current 4080 x 1440, maximum 8192 x 8192
eDP-1 connected primary 2160x1440+0+0 (normal left inverted right x axis y axis) 275mm x 183mm
   2160x1440     60.00*+

DP-1 connected 1920x1080+2160+0 (normal left inverted right x axis y axis) 521mm x 293mm
   1920x1080     60.00*+  50.00    59.94  

Both screens use core display output. Before adding a second monitor, GNOME used 1.25 scaling, and the system used 100% scaling globally. After adding a second monitor, due to the high DPI of the built-in display, the content of the external display is doubled, and browsing the web can be done, but it is inconvenient to adjust the font back and forth when writing the program.

xrandr configuration ideas

xrandr official wiki: https://wiki.archlinux.org/index.php/Xrandr
HiDPI official wiki: https://wiki.archlinux.org/index.php/HiDPI

xrandr is Xorg's official configuration tool for randr. The underlying principle is also to stitch the display content of the two screens to a "canvas" according to the given parameters, and then output. The size of the canvas is equal to the sum of the physical resolution * scaling factor of the two screens. When no configuration is made, Xorg configures both monitors with a scaling factor of 1.0 by default. Therefore, in the same 200DPI situation, the external display display is too large.

In order to prioritize the display quality of the built-in screen, we use a unified DPI = 200 for configuration. Therefore, the configuration idea is to keep the area of the built-in display on this "canvas" unchanged, expand the canvas of the external display, and realize the increase of display content in the same physical display area to achieve the purpose of shrinking.

Configuration process

According to the formula officially given by HiDPI, the command is as follows:

xrandr --output eDP-1 --auto --output HDMI-1 --auto --panning [C*E]x[D*F]+[A]+0 --scale [E]x[F]  --right-of eDP-1
# Generically if your HiDPI monitor is AxB pixels and your regular monitor is CxD and you are scaling by [ExF], the commandline for right-of is:

Take this article as an example:

xrandr --output eDP-1 --auto --output DP-1 --auto --panning 2880x1620+2160+0 --scale 1.5x1.5 --right-of eDP-1

Both monitors are configured for auto mode ,-- panning parameter sets the mouse desirable range. Be sure to pay attention to the setting of this parameter, otherwise the mouse may not move normally. After the command is executed, Ubuntu automatically adjusts the global zoom ratio to 200%, and after manually adjusting it back to 100%, the two screen display areas overlap and the mouse position is abnormal. In addition, there is a problem with mouse flickering on the built-in monitor. The good news is that at 200% zoom, the display ratio of the two screens is the same, and there is no problem of one side being large and one side being small, proving that the overall idea is feasible. Next, it's time to fill in the pits.

Exceptions caused by global scaling adjustments

In this area, Gnome did a lot worse than the original Ubuntu Desktop, and I didn't expect so much trouble. Presumably, there may be a problem with the --auto parameter in xrandr, where xrandr does not correctly recognize and apply the configuration file after the scaling is adjusted. Then specify the required parameters one by one:

xrandr --dpi 200 --fb 5040x1620 --output eDP-1 --mode 2160x1440 --pos 0x0 --output DP-1 --scale 1.5x1.5 --pos 2160x0 --panning 2880x1620+2160+0

--dpi: Forces global use of 200% dpi
--fb: specifies the canvas size. Parallel parallel of two monitors prevents lateral parallelism, so the long side = 2160 + 1920 * 1.5 = 5040; the short side takes 1620 (the larger values of 1440 and 1080*1.5).
--pos: specify the position of the monitor, notebook on the left, pos=0x0; The second monitor is on the right side, pos=2160x0

After setting, the display effect returns to normal, but the mouse flickering problem is still not solved.

Resolving mouse flickering: metaphysical parameters

Adjust the display scale of the built-in monitor to: --scale 0.9999x0.9999.

Full command:

xrandr --dpi 200 --fb 5040x1620 --output eDP-1 --mode 2160x1440 --pos 0x0 --scale 0.9999x0.9999 --output DP-1 --scale 1.5x1.5 --pos 2160x0 --panning 2880x1620+2160+0

In addition to this workaround, there are also posts pointing out that modifying Xorg's configuration file is the fundamental solution. The method is: Create a 20-intel.conf file under /etc/X11/xorg.conf.d/ with the following contents:

Section "Device"
    Identifier "Intel Graphics"
    Driver "intel"
    Option  "AccelMethod"  "sna"
    Option "TearFree" "true"

The above may apply to older Intel graphics. My actual measurement on UHD620 (8th generation i5) did not solve mouse flickering, but added water ripple, twill and other problems. Written here for informational purposes only.

In the end, there will still be a little problem, first of all, after removing the second monitor, it cannot be automatically restored, and you need to execute xrandr --auto again. A little twill and water ripple can still be seen when you quickly drag the window, but it does not affect the use after all, and we will explore the reasons later.