Docking Rule for ThinkPad Thunderbolt 3 Dock Gen 2

It is very convenient to switch between different monitor layouts when using a laptop with multiple external monitors. A very good guide can be found on GitHub Gist by seanf. This post should contain the necessary information for getting it to work on a ThinkPad Thunderbolt Dock.

Udev Hook for Triggering the Switch

Fist create a new udev rule at /etc/udev/rules.d/81-thinkpad-dock.rules:

1SUBSYSTEM=="input", ACTION=="add|remove", ENV{ID_VENDOR_ID}=="17ef", ENV{ID_MODEL_ID}=="3083", TAGS=="power-switch", RUN+="/etc/sbin/thinkpad-dock.sh"

Now reload the udev rules using sudo udevadm control --reload-rules && sudo udevadm trigger.

The rule triggers the script as soon as the power button on the dock is recognized.

Script for Switching Between Layouts

The following snippet shows the script I’m using. Therefore, you have to change the username variable. You may have to adjust the sleep delays manually. There is currently no way to determine when the dock is ready to switch on the external monitors.

 1#!/bin/sh -e
 2
 3# Save this file as /etc/sbin/thinkpad-dock.sh
 4
 5# NB: you will need to modify the username and tweak the xrandr
 6# commands to suit your setup.
 7
 8# wait for the dock state to change
 9sleep 1
10
11username=max
12
13if [[ "$ACTION" == "add" ]]; then
14  DOCKED=1
15  logger -t DOCKING "Detected condition: docked"
16elif [[ "$ACTION" == "remove" ]]; then
17  DOCKED=0
18  logger -t DOCKING "Detected condition: un-docked"
19else
20  logger -t DOCKING "Detected condition: unknown"
21  echo Please set env var \$ACTION to 'add' or 'remove'
22  exit 1
23fi
24
25
26function switch_to_local {
27  export DISPLAY=$1
28
29  su $username -c '
30	xrandr --output eDP1 --auto --primary \
31		--output HDMI1 --off \
32		--output HDMI2 --off \
33		--output DP1 --off \
34		--output DP2 --off \
35		--output DP2-1 --off \
36		--output DP2-2 --off \
37		--output DP2-3 --off
38    '
39}
40
41function switch_to_external {
42  export DISPLAY=$1
43
44  su $username -c '
45	xrandr --output eDP1 --off --primary \
46		--output HDMI1 --off \
47		--output HDMI2 --off \
48		--output DP1 --off --output DP2 --off \
49		--output DP2-1 --off \
50		--output DP2-2 --primary --auto \
51		--output DP2-3 --off
52   '
53
54 sleep 1 
55  
56  su $username -c '
57	xrandr --output eDP1 --off \
58		--output HDMI1 --off --output HDMI2 --off \
59		--output DP1 --off --output DP2 --off \
60		--output DP2-1 --off --output DP2-2 --auto \
61		--output DP2-3 --right-of DP2-2 --auto
62  '
63
64# Switching both external monitors at once can cause "Configure crtc 2 failed"
65#  su $username -c '
66#	xrandr --output eDP1 --off --primary \
67#		--output HDMI1 --off \
68#		--output HDMI2 --off \
69#		--output DP1 --off --output DP2 --off \
70#		--output DP2-1 --off \
71#		--output DP2-2 --primary --crtc 1 --mode 1920x1080 --pos 0x0 \
72#		--output DP2-3 --right-of DP2-2 --crtc 0 --mode 1920x1080 --pos 1920x0
73#	'
74}
75
76case "$DOCKED" in
77  "0")
78    #undocked event
79    switch_to_local :0 ;;
80  "1")
81    #docked event
82    switch_to_external :0 ;;
83esac

If you are using systemd then you can view the logged messages using journalctl -t DOCKING. Note that I’m running xrandr twice as I have two external monitors. Switching them in one command causes the error Configure crtc 2 failed. I was not able to circumvent this reliably.

It is possible to test the script using:

1ACTION=add /etc/sbin/thinkpad-dock.sh

and:

1ACTION=remove /etc/sbin/thinkpad-dock.sh

Do you have questions? Send an email to max@maxammann.org