Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems

Ubuntu 15.10: Handling Dell Latitude laptop dock events to reconfigure displays Linux

Posted by Admin • Tuesday, April 12. 2016 • Category: Linux

Couldn't find any good solutions out there. I have a Dell Latitutde E6410 running Ubuntu 15.10 with XFCE (no Gnome or KDE). I use a physical docking station that allows me to use two external monitors. Ubuntu doesn't seem to understand that if these external monitors vanish, it should switch to the monitor that remains (built-in LCD), and vice versa, so I have to automate it myself.

The trick to doing this reliably is finding a udev device you can monitor using udev rules and perform actions when it appears or disappears. This would be a device that is 100% absent when undocked and is 100% present when docked. There is no kernel built-in dock device on these laptops. In order to watch what devices are coming and going, I used the following command (as root):
udevadm -p -u
Run that in a terminal, undock/dock and see what it says. You may want to save the output to a file, it's a lot. In my case, there was nothing definitive. There is "drm" device which sounds promising, but there is no good way to tell a "remove" apart from an "add" event. Ultimately, I settled on the numlock event. Why? Because it is specific to my external USB keyboard (Microsoft 4000) that is always plugged into the docking station. The internal laptop keyboard is unlikely to generate that event, and the full-size keyboard always produces one. Here is the relevant remove event:

UDEV  [153679.602258] remove   /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.2/1-1.1.2:1.0/0003:045E:00DB.0011/input/input39/input39::numlock (leds)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.2/1-1.1.2:1.0/0003:045E:00DB.0011/input/input39/input39::numlock
SEQNUM=3521
SUBSYSTEM=leds
USEC_INITIALIZED=153679593133
Now, to be 100% sure I could match this event using the literal DEVPATH, but I'll likely forget if I ever change keyboards. So I'll use a wildcard. OK so here is how to do it.

Setting it up

First, Detect dock/undock

/lib/udev/rules.d/85-latitude-dock.rules:
SUBSYSTEM=="leds", DEVPATH=="*::numlock", ACTION=="remove", RUN+="/usr/local/bin/undock.sh"

SUBSYSTEM=="leds", DEVPATH=="*::numlock", ACTION=="add", RUN+="/usr/local/bin/dock.sh"

What this does:

Matches all events of type "leds" with devpath ending in numlock. See the above event for details. Once detected, a shell script is run. This should work for any external keyboard. If you get false triggers from the internal, maybe change the DEVPATH to "*usb*::numlock"?

Then, Reconfigure displays

/usr/local/bin/dock.sh:
#!/bin/bash

sleep 1
logger -t dock "Dock script invoked"
MY_USER=some_username

sudo -u $MY_USER bash -c 'DISPLAY=:0 xrandr --output eDP1 --off' 2>&1 | logger -t dock
sudo -u $MY_USER bash -c 'DISPLAY=:0 xrandr --output HDMI1 --auto' 2>&1 | logger -t dock
sudo -u $MY_USER bash -c 'DISPLAY=:0 xrandr --output VGA1 --auto --right-of HDMI1' 2>&1 | logger -t dock

exit 0
undock.sh is similar, it turns off external monitors and enables eDP1. I'm skipping it for brevity - you'll want to adjust the scripts to your needs anyway, and don't forget to chmod a+x on both.

What this does:

Runs xrandr as user $MY_USER (change the value) to reconfigure displays. In my case, I need to turn off eDP1 (built-in LCD) first, then enable the others. My laptop doesn't like this done on one command (doesn't work), so I separate them into 3. Note the logger calls - if this doesn't work, you can check your /var/log/syslog for the reasons.

Note, you can use Autorandr in place of the dock/undock shell scripts, it may be more user friendly.

Other options: You could make the scripts do something else (or in addition). For example, you can have them enable/disable wireless networking or brighten the screen, etc

0 Trackbacks

  1. No Trackbacks

0 Comments

Display comments as (Linear | Threaded)
  1. No comments

Add Comment


You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

What is the primary language of this blog? (Anti-SPAM question)


Submitted comments will be subject to moderation before being displayed.