---
author:
    email: mail@petermolnar.net
    image: https://petermolnar.net/favicon.jpg
    name: Peter Molnar
    url: https://petermolnar.net/
lang: en
published: '2024-05-06T14:00:00+01:00'
summary: 'DPI change on docking with XFCE and systemd on Manjaro'
tags:
- desktop
- linux
title: How to change DPI when docking with XFCE and systemd

---

A little while ago I got a ThinkPad X1 Carbon 7th gen[^1] from my father that replaced my aging X250. I've been resisting the thinner and thinner trends, but I have to admit, it's a lovely machine, with an incredible keyboard, and a wonderful display. The 8GB fixed RAM sounds is limiting, but for me, it's all right. It stays significantly colder, than the X250, and after upgrading the SSD to 2TB, now that they are available and don't cost an arm and a leg, I don't need the secondary HDD like I used to.

The display, however, poses a problem: it's WQHD, 2560 * 1440 pixels. I know that these days people go for 4k with insane refresh rates, but on a 14" display, I have no need for either: full HD, 1920 * 1080 would be perfectly fine. To achive something like this I set the DPI of the system to 120, all good.

Until I dock it, because the 23" monitor is, indeed, 1920 * 1080, and with 120 DPI, it takes me back in time to much smaller resolutions. Note: I only use a single monitor either way. If I have more, I tend to put up too many distractions: I used to use 2 monitors, one for the tasks, the other for communication, but it's not nearly as productive as many people believe it to be. 

It was easy to fix this by hand: every time I docked, I ran a script, but it was hard to believe there's no way to automate this. Well, there's no built in way, but there is certainly a way.

I use XFCE as my desktop, which provides me with `xfconf-query`. It has a monitor mode to display changes. I set up a profile for the docked display layout:

![XFCE display dialogue with the Advanced tab open, showing a save profile](xfce-display-advanced-dialog.png)

Once that was done, `xfconf-query --monitor --channel displays --verbose` had the following outputs on docking:

```
set: /Default/DP-2/Active (false)
set: /ActiveProfile (554a6d9a9dfdb915105b05437cdcf1a73ac5badd)
set: /Default/eDP-1/Active (false)
set: /Default/DP-2/Active (true)
```

and the following on un-docking

```
set: /ActiveProfile (Default)
set: /Default/eDP-1/Active (true)
set: /Default/eDP-1/Position/X (0)
```

So I wrote a bash script to monitor it, following a tip that I wasn't aware with `while` and `tail`[^2]:

`~/.local/bin/dpi-daemon.sh`

```bash
#!/usr/bin/env bash

xfconf-query --monitor --channel displays --verbose | while read -r line; do
    if grep 'set: /ActiveProfile (554a6d9a9dfdb915105b05437cdcf1a73ac5badd)' <<< "${line}"; then
        xfconf-query -c xsettings -p /Xft/DPI -s -1
    elif grep 'set: /ActiveProfile (Default)' <<< "${line}"; then
        xfconf-query -c xsettings -p /Xft/DPI -s 120
    fi
done
```

Initially I tried to start this from `Session and Startup` but that wasn't happy, so I tried with a `systemd` user unit file:

```bash
mkdir -p ~/.local/share/systemd/user/
```

`~/.local/share/systemd/user/dpi-daemon.service`

```ini
[Unit]
Desription=DPI changer

[Service]
Type=simple
ExecStart=~/.local/bin/dpi-daemon.sh
Restart=always

[Install]
WantedBy=multi-user.target
```

```bash
systemctl --user daemon-reload
systemctl --user enable dpi-daemon
```

Which made everything and every happy: automated DPI change on display change. 



[^1]: https://www.notebookcheck.net/Display-Check-Lenovo-ThinkPad-X1-Carbon-2017-i5-WQHD-Laptop.242798.0.html
[^2]: https://stackoverflow.com/a/77101743