Automatically adjust font scaling factor on monitor connect?

I want my font scaling factor — org/gnome/desktop/interface/text-scaling-factor in dconf — to automatically adjust based on whether a monitor is connected. I’m trying to achieve this with a udev rule that runs a script on monitor connectivity changes. I’ve added a file called 99-monitor-hotplug.rules under /etc/udev/rules.d with the following content:

SUBSYSTEM=="drm", ACTION=="change", ENV{HOTPLUG}=="1", RUN+="/usr/local/bin/" checks whether a monitor is connected, and sets the right value for the user using sudo -Hu michaelmouf gsettings set:

function monitorConnected () { 
    statuses=$(cat /sys/class/drm/card0-DP-{1,2,3,4}/status 2>/dev/null) 
    for status in ${statuses[@]} 
        [[ ${status} == "connected" ]] && return 0 
    return 1 
if monitorConnected; then 
    echo "connected" 
    sudo -H -u michaelmouf bash -c "gsettings set org.gnome.desktop.interface text-scaling-factor 1" 
    echo "disconnected" 
    sudo -H -u michaelmouf bash -c "gsettings set org.gnome.desktop.interface text-scaling-factor 1.3" 

The problem is that even though the dconf value is updated (checked using dconf read and dconf-editor), existing applications do not redraw with the updated font scaling factor. Applications launched after the script runs, however, use the updated value.

How can I get existing applications to update? Alternatively, is there a better way to solve the overall issue of automatically adjusting font scaling on monitor connect / disconnect? This following comment from a mailing list thread I came across suggests that this is discouraged usage:

If you are writing a Debian package’s “maintainer scripts” (e.g.
postinst) and you find yourself writing things like

su - user -c “gsettings set something.something something”

then please try to avoid doing that: it is not how GSettings or dconf are
meant to work, and it is not how maintainer scripts are meant to work
either. It is almost always inappropriate for system-level code to
run commands in a per-user context like that.

Answering myself as I was able to solve this: my problem was that the udev rule was running the script as root. Changing the udev rule to the following:

SUBSYSTEM=="drm", ACTION=="change", RUN+="/bin/su michaelmouf -c '/home/michaelmouf/bin/'"

and moving the script to ~/bin and removing the sudo -us before the gsettings set commands did the trick!

1 Like