How to run script after resume and after unlocking screen
In Ubuntu 12.04 LTS, I would like to run scripts after resuming from suspend, and after unlocking my desktop. These need to run as my user, and with access to my $DISPLAY
.
In particular, I would like to
- restart
nm-applet
to work around bug 985028 - show a custom notification using
notify-send
- possibly other stuff when I get these working
When I resume, scripts in /etc/pm/sleep.d/
are run, but they run as root, without knowledge of my screen and username. It might work if I hard-code my username and export
the default DISPLAY :0
in these scripts, but that feels like a very ugly hack.
Scripts in ~/.config/autostart/xyz.desktop
run after login, but they don't run after merely unlocking the screen after resume.
Is there a way to run scripts after unlocking the screen after a resume?
It looks like you have to hard code the username in the previous answer anyways, so here's a simple script for in /etc/pm/sleep.d if anyone is looking for a quick fix:
#!/bin/bash
case "$1" in
hibernate|suspend)
sudo -u USERNAME env DISPLAY=:0 zenity --info --text "do stuff on suspend"
;;
thaw|resume)
sudo -u USERNAME env DISPLAY=:0 zenity --info --text "do stuff on resume"
;;
esac
This question at the Unix & Linux site documents an alternative approach using dbus messages:
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | \
( while true; do
read X;
if echo $X | grep "boolean true" &> /dev/null; then
SCREEN_LOCKED;
elif echo $X | grep "boolean false" &> /dev/null; then
SCREEN_UNLOCKED;
fi
done )
(Replace SCREEN_LOCKED and SCREEN_UNLOCKED with the actions you want to perform.)
Using xrandr 1>/dev/null 2>1
as the action on unlocking fixed my problem that monitor resolutions/positions were not being correctly restored on screen unlocking (xrandr seems to cause a re-reading of screen settings). I added this line as a background task in my .bash_profile (strictly it might be better as a desktop file in ~/.config/autostart, since that only runs when you start gnome):
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | \
( while true; do
read X;
if echo $X | grep "boolean false" &> /dev/null; then
xrandr 1>/dev/null 2>1;
fi
done ) &
Further background on the gnome-screensaver API can be found at this site, and on the dbus monitor here.
One solution is a script which runs when logging into the desktop, and which catches dbus messages. After resume from suspend the screen is locked, and after entering the password, there is an Unlock event on dbus.
(Thanks to Kim SJ for putting me on the right track. I have no ScreenSaver signals, but found another interface to use).
In ~/.config/autostart/
, I have a .desktop file which starts a bash script:
$ cat ~/.config/autostart/mymonitor.desktop
[Desktop Entry]
Categories=System;Monitor;
Comment=Monitor dbus for unlock signals
Exec=/usr/local/bin/unlock_monitor
Name=unlock_monitor
Type=Application
The unlock_monitor
monitor script reads dbus messages from com.canonical.Unity.Session
and does stuff on Unlocked
signals:
#!/bin/bash
dbus-monitor --session "type=signal,interface=com.canonical.Unity.Session" --profile \
| while read dbusmsg; do
if [[ "$dbusmsg" =~ Unlocked$ || "$dbusmsg" =~ NameAcquired$ ]] ; then
sleep 5
notify-send "$(basename $0)" "Unlocked or freshly logged in..."
# ...
fi
done
When logging in, there is no "Unlocked" signal, but there is a "NameAcquired" signal when dbus-monitor
starts.