HOWTO set DPI in Xorg

From LinuxReviews
Jump to navigationJump to search

Configuring a correct dots per inch settings for the Linux X display server will make fonts scale so they are big enough to be readable on modern high resolution monitors and it will also make other elements, in some programs, larger. The correct resolution and screen dimensions are typically detected correctly by the X server yet the DPI values for both the X server and X servers font rendering mechanism are not set automatically. You will have to configure those DPI values yourself. Doing so can be done in several ways.

Introduction

Configuring the correct dot per inch setting for your display in Linux should ideally not be required; it could be auto-detected and auto-configured but it is not. X will insist that your DPI is 96x96 even if it knows it isn't.

To complicate matters, there are actually two DPI settings of importance: The X server DPI and the font DPI. They are both set to 96 even if the X server knows the correct DPI.

The current X server DPI setting can be checked with:

xdpyinfo | grep -B2 resolution

and the typically more important font DPI setting can be checked with:

xrdb -query |grep dpi

How To Tell What DPI You Have

The command xrandr |grep "connected pri" will in most cases give you a line which ends with your primary monitors dimensions. It will produce a line like:

eDP1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 340mm x 190mm

The xrandr output would indicate that X totally knows DPI given that it has the screen resolution and the screen dimentions. However, a close-up inspection of:

xdpyinfo | grep -B2 resolution will tell you resolution: 96x96 dots per inch even so - unless you have configured X to use a different DPI setting. There are several ways of doing this. The first one is laughable:

for i in 1 2;do
xrandr --fbmm `xrandr | sed -n '/ connected / {s/.* \([0-9]\+\)mm x \([0-9]\+\)mm/\1x\2/p;q}'`
done

Running xrandr with the --fbmm parameter and a resolution twice makes xdpyinfo | grep -B2 resolution show the screens correct DPI size instead of the hard-coded 96x96 value. Why the -fbmm parameter doesn't "take" the first time it is set is a unsolved mystery.

The website sven.de/dpi/ has a DPI Calculator you can use to get a correct DPI value for any monitor if you know the resolution and the diagonal size in inches.

How To Permanently Set Your Display DPI

There are three not great options for setting the X server DPI. You can create a file in /etc/X11/xorg.conf.d/ with a Monitor section with a DiaplaySize value:

File: /etc/X11/xorg.conf.d/40-dpi.conf
# Will set your DPI to 141x141 if the screen is 1080p
Section "Monitor"
    Identifier   "<default monitor>"
    DisplaySize  340 190    # In millimeters
EndSection

A second option is to run xrandr --dpi VALUE twice in a script executed upon login. Running it once should obviously be enough but it isn't. xrandr --dpi 141 will produce the same result as the above configuration file.

A third option is to add --dpi to the Xorg server startup command. That command would depend on the login manager you are using. That would be /etc/lightdm/lightdm.conf or a configuration file in /etc/lightdm/lightdm.conf.d/ if you are using lightdm. For example:

File: /etc/lightdm/lightdm.conf.d/dpi.conf
[SeatDefaults]
xserver-command=X -dpi 141

Setting the DPI using X -dpi is the best option if you have a multi-monitor setup.

Lovelyz Kei ProTip.jpg
TIP: A DPI setting based on 96 may produce less artifacts in those applications who do care about the X DPI setting. You may want to use 96, 120 (25% higher), 144 (50% higher), 168 (75% higher), 192 (100% higher) if any of those values are close to your DPI. There is, in practice, not that much difference so if you think 144 is slightly too big for a 15.5" 1080p display then you're better off using the correct DPI of 141.

You can verify that the right X server DPI setting is in effect with xdpyinfo | grep -B2 resolution

The more important font DPI setting can be configured by either changing the default Xft.dpi: 96 setting in /etc/X11/Xresources OR by creating a $HOME/.Xresources file with Xft.dpi: VALUE, for example:

File: $HOME/.Xresources
Xft.dpi: 141

This font DPI setting can also be configured in desktop environment specific configuration tools. Xfce has a tool called xfce4-appearance-settings (called "Appearance" in its menu). Font DPI can be set in that configuration tools Fonts tab. KDE Plasma has a similar setting available in systemsettings5 ("System settings" in its menu) under Fonts where you can define a Force font DPI value.

You can verify that the right font DPI setting is in effect with xrdb -query |grep dpi

Do note that setting font DPI does NOT change or affect the X server DPI and a X configuration file with a Monitor section and a DisplaySize setting will or a X startup command with a --dpi VALUE will NOT change the Xft.dpi value accordingly. You will need to change both. The MATE desktop environment is an exception; it will set the Xft.dpi value using the X servers DPI value.

How DPI Values Are Used

The font DPI setting (Xft.dpi) is used by a lot of programs. You will immediately notice a huge difference when that setting is changed, a majority of software applications will change the font size depending on his setting.

The X server DPI is, on the other hand, barely used. Common GUI toolkits like Qt and GTK don't care about that setting, not even a little. Icons and things like that won't change.

Scaling: The Alternative To Caring About Actual Dots Per Inches

GNOME and GNOME "apps"

A big part of the reason why X hard-codes DPI to 96 for both the server and the fonts is that the developers who are heavily in control of both GNOME and GTK are also in positions where they have a lot to say about what goes into X - even though they are entirely focused on Wayland. The "GNOME way" is to use a "scale-factor" set in GNOMEs settings. Scaling has to be set to an integer so you can either have "100%", which is too small given a hard-coded DPI of 96, and "200%", which is too big unless your screen has a DPI at or above 2*96=192. It used to be possible to configure font DPI in GNOME but that was a feature for people with poor eye-sight and GNOME developers hate actually user-friendly features so it had to go. Similarly, icon sizes can be configured for GTK2 applications and GTK 3 had that option in early versions but GNOME developers, who are in control of GTK development, thought it was too useful for visually impaired people so that level of user control over their own desktop systems had to go.

GNOME has a special GNOME scaling system for fonts. It can be configured by setting something called gsettings describe org.gnome.desktop.interface text-scaling-factor this way:

gsettings set org.gnome.desktop.interface text-scaling-factor 1

The above example does nothing since the scale factor is 1. This font scale factor does not have to be set to a whole number, a scale factor of 1.2 or 1.5 would work. You can see what the text-scaling-factor is set to by changing set to get:

gsettings get org.gnome.desktop.interface text-scaling-factor

Setting a GNOME text-scaling-factor is a bad idea unless you use the foot desktop environment and you only run nothing but ueseless foot desktop "apps" within that desktop environment since all well-written applications (=non-GNOME programs) use the X font DPI setting. The result will likely be that GNOME "apps" and real software get different font sizes.

Qt

Qt applications can be and mostly are aware of the X font size setting. They are also capable of scaling icons based on either Qt settings (can be configured with qt5ct) or KDE icon size settings. However, a minority of Qt programs are developed by morons who insist on hard-coding font and icons sizes. This is not recommended by the Qt developer documentation. Regardless, those applications do need to big adjusted and they can be using a environment variable called

QT_SCALE_FACTOR=""

One way to set this on a per-application basis, which is not ideal, is to create scripts in $HOME/bin for silly Qt programs like spectral. That can be done this way:

File: $HOME/bin/spectral
#!/bin/bash
QT_SCALE_FACTOR="1.7" /usr/bin/spectral "${@}"

There is one problem with QT_SCALE_FACTOR that can't be solved: It will scale the application and any dialog box or other window called by the application. If you are using a font DPI and icons sizes that are right for your display and you use QT_SCALE_FACTOR to adjust a poorly written program like spectral then the programs window will look right but things like the file picker will look gigantic since it will also be scaled.

Per-Monitor Scaling Using xrandr

xrandr can be used to make X scale everything on a specific monitor. It can be done like this:

xrandr --output DP-0 --scale 1.5x1.5

There is no equivalent X configuration option or anything like that, you will need to put a xrandr command in some script that is executed when you login to make such scaling permanent.

Scaling using xrandr with --scale is not at all ideal and it may look ugly. However, it is the only solution if you have two monitors with different resolutions since X does not have any method for setting per-monitor DPI sizes, there is only one global setting. Setting a xrandr --scale factor may be desirable if you are using a dual-monitor setup with a 1080p and a 1440p monitor or a laptop monitor with an external display.

Add your comment
LinuxReviews welcomes all comments. If you do not want to be anonymous, register or log in. It is free.