niemueller.de::home niemueller.de
Open Software. Open Knowledge.




 

Tim's WebLog


External monitor on docking station wakeup on F22

The following situation: I have a laptop and two docking stations (DS), one at work and one at home. Both have an external monitor. My setup is to mirror the screens (same resolution on both) so that I use the external screen and keep the lid closed (I'm not so much a multi-screen person). Further, most of the week I find myself simply plugging in my laptop and hitting the DS power button at work in the morning and putting it to sleep using the DS power button and unplugging it in the evening without ever opening it in between.

Now the problem is, that the mirroring will then not be properly enabled (or for any other reason the external screen does not get a signal). The manual workaround is to open the lid, start the display settings (gnome-control-center display). That will enable the external monitor (I guess during probing). Obviously this is rather annoying over time, so the following describes a workaround. The idea is to react to an event that is triggered on wakeup, check if an external monitor is connected, and if so briefly disable and re-enable it.

Step 1: Add a service called when resuming
That used to be somehow simpler, either through pm-utils or acpid. Now it's the magic of systemd. This is fine, but I wish they would just have a compatibility script calling pm-utils scripts. However, the first thing to do is create a file /etc/systemd/system/resume@.service (exactly that name, in particular with the @ at the end) with the following content (courtesy of the fine Arch Linux power management documentation):

[Unit]
Description=User resume actions
After=suspend.target

[Service]
User=%I
Type=simple
ExecStart=/usr/local/bin/resume.sh %I

[Install]
WantedBy=suspend.target

This simply calls a script with what will be a username. Create /usr/local/bin/resume.sh with the following content:

#!/bin/bash

SCRIPT=/home/$1/bin/resume.sh

if [ -x $SCRIPT ]; then
	$SCRIPT
	exit $?
else
	echo 2
fi

It simply allows to have user-specific resume scripts. You can leave out this middleman and simple add your full script path as ExecStart in the unit file.

Finally, we need to enable the systemd unit for a particular user. In my case this is achieved using sudo systemctl enable resume@tim.service. Edit for your username accordingly.

Step 2: resume script
Add your local resume script in $HOME/bin/resume.sh to contain (at least) the following:

#!/bin/bash

PORT=DP2-2
DOCKED=$(cat /sys/devices/platform/dock.0/docked)

if [ "$DOCKED" != "1" ]; then exit 0; fi

export DISPLAY=:0
export XAUTHORITY=/home/user/.Xauthority

if (xrandr -q|grep $PORT|egrep -qv disconnected); then
	xrandr --output $PORT --off
	sleep 1
	xrandr --output $PORT --preferred
	exit 0
fi

exit 1

This will check if the laptop is docked and otherwise quit. I then checks for the connected display and calls xrandr to disable and re-enable the external screen. Update the PORT variable accordingly (check xrandr output). You can disable the DOCKED check to use this with an arbitrary external monitor.

Maybe this helps another soul to get rid of this problem. However, you'll have a new one afterwards: gnome-shell will often crash on resume. It'll recover (most of the time), but anyway.

Comments for this posting

I achieved the same, using a smiler method, http://blog.rabin.io/linux/networkmanager-using-dispatcher-d-to-run-scripts-based-on-network-connectivity





Top 5 Pages
Wiki
WebLog
SquidGuard Webmin Module
Onager
Network Utilities Webmin Module




Palm Software
UniMatrix UniMensa UniSorter
UniChat OHS Mobile Onager


My Bookshelf




Valid XHTML 1.1!

RSS Copyright © 2000-2016 by Tim Niemueller