I have in /etc/udev/rules.d/80-monitor.rules
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", ENV{DEVNAME}=="dri/card0", RUN+="/etc/udev/monitors.sh"
Then in /etc/udev/monitors.sh
(marked executable):
#!/bin/sh
set -e
export DISPLAY=:0
export XAUTHORITY=$(getent passwd $(w -h -s|awk '$3==":0"{print $1}'|sed 1q)|cut -d: -f6)/.Xauthority
desktop() {
xrandr --output LVDS1 --off || true
xrandr --output HDMI3 --auto --primary --output HDMI2 --auto --right-of HDMI3
}
laptop() {
xrandr --output HDMI3 --off || true
xrandr --output HDMI2 --off || true
xrandr --output LVDS1 --auto
}
if xrandr|grep -q 'HDMI2 connected'; then
desktop
else
laptop
fi
Some hints and catches with this example:
- It only works for the first graphically logged in user.
- You'll need to tune the script to match your monitor setup. See the xrandr manpage for help with this.
- I'm not sure if the udev rule will match everyone's monitor status change event. I used
udevadm monitor --property
to figure out what to use.
- I had to use
--off
to turn off all displays explicitly first before reconfiguring before xrandr allowed me to configure new ones. I think this is driver-dependent and not well documented.
- I'm using the presence of the external screen to decide which way round to reconfigure. This might not work for everyone.
- xrandr sets some resolution by default which was optimal for me. See the manpage for details on how to set custom resolutions if you need.