Skip to content

Instantly share code, notes, and snippets.

@aral
Last active August 17, 2021 17:10
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aral/9cf2eee6d7e13556b6aed2bb118d3c8b to your computer and use it in GitHub Desktop.
Save aral/9cf2eee6d7e13556b6aed2bb118d3c8b to your computer and use it in GitHub Desktop.

Why

  • You have a laptop with a 13" screen and 1920x1080 resolution and a 4K external monitor.
  • You run the laptop at 1x scale.
  • You run the 4K screen at 2x scale (pixel doubled).
  • You’re running elementary OS 5.x (Hera) or elementary OS 6 (Odin)

Which means that text scale should be 1x when the 4K monitor is plugged in but it should be larger than that (at least ~1.5x) to be legible on the laptop’s screen. (Yes, the manufacturer of the laptop chose the wrong resolution for the screen. It should have been QHD (2560 × 1440) or at most QHD+ (3200×1800) so that you could run it confortably pixel doubled.)

Anyway, it’s not and you’ve already bought it (and it’s otherwise an excellent laptop) but you don’t want to change the text scale every time you plug it into and unplug it from your external monitor.

How

You need to add a udev rule that gets triggered whenever your screen setup changes (fun fact: you listen for the drm event – sigh – the state of things!) and then run a script that sets the text-scaling-factor accordingly.

  1. Configure the 80-personal.rules script (see instructions in script) and then place it in /etc/udev/rules.d/
  2. Configure the auto-text-scale.shscript (see instructions in script) and save it somewhere. Make sure you set it as executable: chmod +x auto-text-scale.sh.
  3. Reload your udev rules: sudo udevadm control --reload

You can also test your rules (they will not run but it will show you if they would run were this not a test). Again, customise for your own device:

udevadm test --action="change" /devices/pci0000:00/0000:00:02.0/drm/card0

# Rule for executing commands when an external screen is plugged in.
# Credits go to: http://unix.stackexchange.com/questions/4489/a-tool-for-automatically-applying-randr-configuration-wh$
# Via https://ruedigergad.com/2012/01/28/hotplug-an-external-screen-to-your-laptop-on-linux/
# Update the path to your home directory and the path to the script file according to your own setup.
ACTION=="change" \
, KERNEL=="card0" \
, SUBSYSTEM=="drm" \
, ENV{DISPLAY}=":0" \
, ENV{XAUTHORITY}="/home/aral/.Xauthority" \
, RUN+="/home/aral/auto-text-scale.sh"
#!/bin/bash
# Get the actual account id as gsettings needs to be set for my account.
# Thanks to: https://unix.stackexchange.com/posts/623179/revisions
RUID=$(who | awk 'FNR == 1 {print $1}')
RUSER_UID="$(id -u ${RUID})"
# Get the status of my external monitor.
# (Your device details will vary. Use sudo udevadm monitor to find it.)
# Thanks to: https://frdmtoplay.com/i3-udev-xrandr-hotplugging-output-switching/
if [[ $(</sys/class/drm/card0/card0-DP-1/status) == "connected" ]]; then
# echo `date` '- External 4K screen connected. Setting text scale factor to 1.0.' >> /tmp/monitor-log.txt
sudo -u ${RUID} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${RUSER_UID}/bus" /usr/bin/gsettings set org.gnome.desktop.interface text-scaling-factor 1.0
else
# echo `date` '- External screen not connected. Setting text scale factor to 1.75.' >> /tmp/monitor-log.txt
sudo -u ${RUID} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${RUSER_UID}/bus" /usr/bin/gsettings set org.gnome.desktop.interface text-scaling-factor 1.75
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment