Skip to content

Instantly share code, notes, and snippets.

@Lahorde
Last active August 31, 2018 07:48
Show Gist options
  • Save Lahorde/8988eb548ba5361512de1ee06952a9cd to your computer and use it in GitHub Desktop.
Save Lahorde/8988eb548ba5361512de1ee06952a9cd to your computer and use it in GitHub Desktop.
Handle several monitor hotplug efficiently

Description

Scripts to configure monitor hotplug. It is useful on a laptop that can be connected to some external screens.

Issues

In some cases, when monitor configuration changes plank position is not updated accordingly. A workaround consist in restarting plank. It is killed from monnitor_hotplug.sh script and automatically restarted using plank_forever.sh script that is started from xfce startup application menu.

References

#/etc/udev/rules.d/95-monitor-hotplug.rules
ACTION=="change", KERNEL=="card[0-9]", SUBSYSTEM=="drm", RUN+="/usr/bin/systemctl start monitor_hot_plug.service"
#/etc/systemd/system/monitor_hot_plug.service
[Unit]
Description=Monitor hotplug
[Service]
Type=simple
RemainAfterExit=no
User=remi
ExecStart=/usr/local/bin/monitor_hotplug.sh
[Install]
WantedBy=multi-user.target
#!/bin/bash
######################################
## /usr/local/bin/hotplug_monitor.sh
######################################
X_USER=remi
MONITOR_0='eDP-1'
MONITOR_2='VGA'
XFCE_PANEL_NAME='panel-1'
export DISPLAY=:0
export XAUTHORITY=/home/$X_USER/.Xauthority
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
function add_monitor()
{
echo "connect monitor $1"
#dual monitor - $1 on right - xfce panel on left of MONITOR_0
xrandr --output $1 --right-of $MONITOR_0 --preferred --output $1 --primary >> /tmp/screen
#Set xfce panel on primary monitor
# Either use soft solutions but sometimes it does not work
#xfconf-query -v -c xfce4-panel -p /panels/${XFCE_PANEL_NAME}/output-name -s $1
# Or restart panel
xfce4-panel -r
#reload conky
killall -s SIGUSR1 conky
# kill plank - it will be automatically restarted by plank_forever.sh script
killall -s SIGHUP plank
}
function use_laptop_monitor(){
xrandr --output $MONITOR_0
#Set xfce panel on MONITOR_0
# Either use soft solutions but sometimes it does not work
#xfconf-query -c xfce4-panel -p /panels/${XFCE_PANEL_NAME}/output-name -s $MONITOR_0
# Or restart panel
xfce4-panel -r
#reload conky
killall -s SIGUSR1 conky
# kill plank - it will be automatically restarted by plank_forever.sh script
killall -s SIGHUP plank
}
# card name can change : https://unix.stackexchange.com/questions/364246/nondeterministic-graphic-cards-device-names
# do not use /sys/class/drm/.../status to get connected devices, they have a different name in xrandr and sys (but we can identify it using edid)
nb_connected_screens_sys_cmd="find /sys/class/drm/*/status -type f -exec grep -ERi "^connected$" {} \; | grep -c "connected""
nb_connected_screens_sys=$(eval $nb_connected_screens_sys_cmd)
nb_connected_screens_cmd="xrandr |grep -E ' connected ' | grep -c "^.*$""
nb_connected_screens=$(eval $nb_connected_screens_cmd)
while [ "$nb_connected_screens_sys" -ne "$nb_connected_screens" ]
do
echo "Number of connected screen at sys level : $nb_connected_screens_sys - at xrandr level : $nb_connected_screens"
nb_connected_screens_sys=$(eval $nb_connected_screens_sys_cmd)
nb_connected_screens=$(eval $nb_connected_screens_cmd)
sleep 0.2
done
echo "number of connected screens = $nb_connected_screens"
# a screen has been removed
if [ $nb_connected_screens -eq 1 ]
then
use_laptop_monitor
# a screen has been added
elif [ $nb_connected_screens -eq 2 ]
then
add_monitor $(xrandr |grep -v 'eDP-1' | grep -E ' connected ' | awk -F ' ' '{print $1}')
else
echo "Cannot handle $nb_connected_screens"
fi
exit 0
#!/bin/sh
while true
do
if ! pgrep plank
then
echo 'start plank'
plank > /dev/null
fi
sleep 1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment