Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems
Linux

Ubuntu 18.04: Handling Dell Latitude laptop dock events to reconfigure displays

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 (Update: these instructions worked fine on a Precision 7510 running Ubuntu 18.04) 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. (Ubuntu 18.04 does in fact notice monitor changes, but insists on arranging the monitors in the wrong order, so this solution is still necessary)



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
udevadm monitor # in Ubuntu 18.x

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.
Markdown format allowed


Submitted comments will be subject to moderation before being displayed.