Recently, I purchased a nice new Lenovo ThinkPad T460s. Naturally, I'm running Ubuntu on it and maintaining my new venture into using the i3 window manager. One problem that I ran into with this was when docking the ThinkPad at work. I wanted to use an external monitor that was plugged into the dock. Since i3 doesn't manage things like this for you, I had to hook into some events that know when the laptop has been docked and undocked and then use
xrandr to hook up the external monitor. This is how I managed to make it work. Albeit, with a few bugs...
First, you need to create a script that will handle your
xrandr commands. I called this script
manage-monitor.sh and I put it inside of
#!/bin/sh export DISPLAY=:1 export XAUTHORITY=/run/user/1000/gdm/Xauthority if [ "$1" = "dock" ]; then logger "ACPI event: Turning on DP2-2. This will take 10 seconds or so..." while (xrandr | grep "DP2-2 disconnected"); do sleep 1 done sleep 1 xrandr --verbose --output eDP1 --off --output DP2-2 --mode 2560x1440 --primary 2>&1 | logger /home/dean/Scripts/background.sh else logger "ACPI event: Turning off DP2-2" xrandr --verbose --output DP2-2 --off --output eDP1 --mode 1920x1080 --primary 2>&1 | logger fi
Just a few notes before moving on
- You must set the
DISPLAYenvironment variable inside of the script. Since it will need it. You can also opt to tell
xrandrdirectly with the
-doption. Usually, I've found that setting this to
:0works, but in my case, it was
- You must set the
XAUTHORITYenvironment variable inside of this script too. This should point to your Xauthority file. Sometimes this is in
~/.Xauthority, but in my case it was in the place shown above. An easy way to find this out is to boot into a workable desktop environment like Gnome and just open a terminal and run
echo $XAUTHORITYand use that.
- The sleeping in the script is due to my monitor being slow to wake up and be available to
xrandr. I was running into issues where I was getting the error
xrandr: cannot find mode 2560x1440and this was due to the monitor not being immediately available by the time the command was run. You may or may not need this extra sleep. I did.
- I'm turning off my laptop screen and turning on my external screen. You can opt to have both on if you'd like, just edit the
xrandrcommand in the script to suit your needs.
- Lots of logging is happening to help you out.
xrandrwith no arguments to see what monitors and modes you have available to you. You may not have a
DP2-2monitor and it may be called something else.
background.shscript that is being run simply resets my background image using
feh. You may not need to do this.
Hooking up the events
udev, you can watch the events that are happening and fire off this script. I created two files in
/etc/acpi/events and they are:
event=ibm/hotkey LEN0068:00 00000080 00004010 action=su dean -c "/etc/acpi/external-monitor.sh dock"
event=ibm/hotkey LEN0068:00 00000080 00004011 action=su dean -c "/etc/acpi/external-monitor.sh undock"
Making sure you have the right event
Notice the weird string for the event? I found these online and it worked properly for me. If these events aren't firing off your script for you, open a terminal and run
sudo acpi_listen. Once you've done this, undock and redock your laptop. You'll see the event keys print out for these events. Copy and paste the correct one into your events file and you should be good.
Once you've done this, reload udev with
sudo udevadm control -R. After this, dock or undock your laptop and things should work. If they don't, take a look at your
syslog file. There should be plenty of logging in there to help you out, as I'm redirecting all of the output from
xrandr and throwing it into syslog. It may be you're not tied to the right events. If you are, at a minimum you should see something in
syslog that says
ACPI event: Turning on ... If you don't see that,
udev hasn't registered the events you're looking for, so you'll have to do what I recommended above with