HiDPI and Multiple Monitors

Hi folks,

I’m using a 4 monitor X setup where only one of the displays is a 4K monitor under 18.04. While MATE Tweak tool allows me to choose “Auto detect”, “Regular”, or “HiDPI”, none of these options seems entirely appropriate for this configuration.

If I choose autodetect or HiDPI, the output on the 4K monitor looks fantastic, the windows and fonts on the non-HiDPI monitors are scaled too large (about 2X as big as if I chose “regular”). If I choose regular, of course, windows anfd fonts in the non-4K displays look great, the way they always did, but of course, windows and fonts on the 4K display are microscopic.

I’m guessing that this setup (multiple monitors, where not all are HiDPI) isn’t currently anticipated by the tweak setting, and I’ll have to punt to something like xrandr scaling to get things “just so”. This post is just a request for confirmation about that. If it’s truly a bug I’ll be happy to play along in an issue tracker about it, though.

  • C
1 Like

AFAIK, different scale factors isn’t possible with X, unfortunately. If/when MATE switches to Wayland, then it could be.

I haven’t tried it yet, but I previously did some googling, and it appears to be nominally possible if you have the patience:

@mcdonc - GTK+ cannot do per-monitor scaling, and X11 doesn’t even know what scaling is… Wayland is too far in the future to even know. Your best bet is xrandr, as you mentioned.

Here’s the script I use for a HiDPI laptop with a regular monitor above it.

#!/bin/sh
# extend non-HiDPI external display on DP* above HiDPI internal display eDP*
# see also https://wiki.archlinux.org/index.php/HiDPI
# you may run into https://bugs.freedesktop.org/show_bug.cgi?id=39949
#                  https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/883319

EXT=`xrandr --current | sed 's/^\(.*\) connected.*$/\1/p;d' | grep -v ^eDP | head -n 1`
INT=`xrandr --current | sed 's/^\(.*\) connected.*$/\1/p;d' | grep -v ^DP | head -n 1`

xrandr --output "${INT}" --auto --output "${EXT}" --auto --scale 2x2 --above "${INT}"

ext_w=`xrandr | sed 's/^'"${EXT}"' [^0-9]* \([0-9]\+\)x.*$/\1/p;d'`
ext_h=`xrandr | sed 's/^'"${EXT}"' [^0-9]* [0-9]\+x\([0-9]\+\).*$/\1/p;d'`
int_w=`xrandr | sed 's/^'"${INT}"' [^0-9]* \([0-9]\+\)x.*$/\1/p;d'`
off_w=`echo $(( ($int_w-$ext_w)/2 )) | sed 's/^-//'`

xrandr --output "${INT}" --auto --pos ${off_w}x${ext_h} --scale 1x1  --output "${EXT}" --auto --scale 2x2 --pos 0x0

basically, you set it to HiDPI mode, and use xrandr to set all the non-HiDPI monitors to --scale 2x2, then you’ll need to reposition where the screens show with relationship to one another, since the size will be all wrong.

I also use autorandr so that it remembers this configuration (so after tweaking it, I run it one last time and save it to autorandr).

Other than that, you can just set your 4K monitor to a lower resolution, but that really sucks :stuck_out_tongue:

1 Like

Your script run perfectly but now I have cursor flickering on my main display. Any idea how to shut it down ?