Building on Brent Roman's answer, I implemented a script using dbus-monitor and afterwards replaced it with gdbus, which has a cleaner interface and clearer output. The script is rather longish, I'll strip anything not-dbus related, to illustrate the point of running a script on screen unlock.
First a sample output from running gdbus, locking the screen and then unlocking it:
paulo@monk:~$ gdbus monitor --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1/session/c2
Monitoring signals on object /org/freedesktop/login1/session/c2 owned by org.freedesktop.login1
The name org.freedesktop.login1 is owned by :1.6
/org/freedesktop/login1/session/c2: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'Active': <false>}, @as [])
/org/freedesktop/login1/session/c2: org.freedesktop.login1.Session.Lock ()
/org/freedesktop/login1/session/c2: org.freedesktop.login1.Session.Unlock ()
/org/freedesktop/login1/session/c2: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'Active': <true>}, @as [])
So, the script skeleton:
OBJECT_PATH=/org/freedesktop/login1/session/$XDG_SESSION_ID
BUS_NAME=org.freedesktop.login1
UNLOCK="$OBJECT_PATH: $BUS_NAME.Session.Unlock ()"
GDBUS_MONITOR="gdbus monitor --system --dest $BUS_NAME --object-path $OBJECT_PATH"
PROGNAME=$(basename "$0")
LOGFILE=~/log/$PROGNAME.log
# ...
function log {
echo "$(date +'%F %T.%3N') [$$]" "$@"
}
# ...
function run_daemon {
exec &>>"$LOGFILE"
kill_running "$GDBUS_MONITOR"
local signal
while read -r signal; do
log "$signal"
if [[ $signal == "$UNLOCK" ]]; then
check_quodlibet
fi
done < <(eval "exec $GDBUS_MONITOR")
}
# ...
run_daemon
Function kill_running checks if there's an instance running and kills it. If the script is autostarted with each lightdm login, we'd have potentially multiple instances running, hence the need to kill any current instances before starting.
Function check_quodlibet restarts quodlibet if the mounted USB device (with my music collection) has been reset (it happens randomly after resuming from suspend). I didn't think it was relevant to include it.
The exec when running gdbus is not strictly necessary, but it then avoids having an extra process, since the script will fork itself before running gdbus. This way, there will be only 2 processes running: the script itself and gdbus.
I created ~/.config/autostart/quodr.desktop (quodr is the name of the script) to have the script started on each lightdm login:
[Desktop Entry]
Version=1.0
Type=Application
Name=quodr
Exec=quodr
Comment=Check if quodlibet needs refresh
Icon=dialog-question-symbolic
Hidden=false
As a TODO to myself: I intend to investigate how to start the script as a systemd user service, D-Bus-activated.
This question with all the answers were invaluable for me to reach this solution. This problem was bugging for a very long time, I had tried many solutions, but I only got a clearer picture of what was necessary after reading what everyone wrote here. Thanks to everyone, and in particular to Brent Roman.
As a last comment, I built and installed d-feet and bustle while I investigated this, they were really useful.
I'm running Xubuntu 17.10.
light-locker(in your casexfce-power-managertogether withupower) so that it will not only callxflock4and thenlight-lockerin advance, but make it more configurable. Best check some more documentation on xfce-power-manager, e.g. from LFS http://www.linuxfromscratch.org/blfs/view/cvs/xfce/xfce4-power-manager.html or upstream docs: http://docs.xfce.org/xfce/xfce4-power-manager/preferences and on systemd ... – doktor5000 May 15 '15 at 07:39org.freedesktop.PowerManagementor related as that is wherexfce4-power-managerregisters: http://git.xfce.org/xfce/xfce4-power-manager/tree/src/org.freedesktop.PowerManagement.Inhibit.xmlsystemd-inhibit --listshould show active inhibitors, for me under KDE e.g. currentlynetworkmanagerandpowerdevil(KDE analogon toxfce4-power-manager) – doktor5000 May 15 '15 at 08:12