Many users’ desktop setups are comprised of several displays with different sizes, pixel resolutions and therefore different pixel densities (dpi). Unfortunately, many applications are not aware of so called ‘HiDPI‘ displays – displays, that by far exceed the pixel density of 72 dpi that we all have come to love so much. The result is that many elements on screen like windows, icons or fonts, are drawn uncomfortably small.
To counter this effect, the KDE desktop environment implements a global scaling factor that multiplies the default size of the elements. So if you set it to 150%, everything gets drawn 50% bigger than normal. The problem that arises here is that it is a global factor, and applies the same to all connected displays. This might be unwanted e.g. you have an additional display connected to your computer that does not have a high pixel density, as is the case for most standard Full-HD displays on the market.
So what do you do then? Either tolerate way too big elements on the non-HiDPI display, or set the scaling factor back to 100% and have a hard time reading anything on your nice HiDPI display?
Having had to deal with this challenge myself, I want to outline for you how I managed to get it working.
Set the scaling factor for your HiDPI display
First, go to System Settings > Display and Monitor > Display Configuration and set the “Global Scale” value to something that fits best to your HiDPI display. You do not need to consider your other display at this point.
Get the measuring tape out
Measure the height of your HiDPI display and the height of your non-HiDPI display. In my case, the values are 337 mm and 287 mm. Make sure to measure the height of the display area, not the whole device.
A little math – but not too much
Once you have the measurements, it is time to do a few simple calculations. We are looking for the ratio of the screen heights. In my case it would look like this:
h_screen_one = 337 mm
h_screen_two = 287 mm
phys_ratio = h_screen_one / h_screen_two
phys_ratio = 337 mm / 287 mm
phys_ratio = 1.174 (rounded)
Because the elements on the non-HiDPI display are way too big right now, we will need to resize the display virtually. That is what the physical ratio is for. In the next step, we multiply the physical ratio with the displays’ resolution to retrieve the virtual resolution.
phys_ratio = 1.174 (calculation above)
res_virtual_width = 1920 * phys_ratio
res_virtual_width = 2254 (rounded)
res_virtual_height = 1080 * phys_ratio
res_virtual_height = 1268 (rounded)
Next, we need to find the scaling factor of the virtual resolution and the HiDPI-displays’ resolution. To do that, we simply divide the resolution width of the hidpi display by the resolution width of the virtual display. Using the resulting scaling factor, we calculate the target screen resolution by multiplying the displays physical resolution with the scaling factor:
res_virtual_width = 2254
res_hidpi_width = 3840
scaling_factor = res_hidpi_width / res_virtual_width
scaling_factor = 1.7 (rounded)
res_width = 1920 * scaling_factor
res_width = 3264
res_height = 1080 * scaling_factor
res_height = 1836
Having calculated the necessary values, it is time to use them. To change the displays position, size and orientation, we are going to use xrandr, which should be available for most Linux distributions. Depending on your specific setup, it might be necessary to set different values for the screens’ positions. Keep in mind that the screens position is always defined as the position of its upper left corner. Also keep in mind that you need to work with your non-HiDPI screens’ virtual resolution.
In this case, the non-HiDPI display is connected via DisplayPort-0, the values are as calculated above.
--output DisplayPort-0 --scale 1.7x1.7 --pos 0x324 \
--output HDMI-A-0 --pos 3264x0