Light Locker - Run script on screen lock/unlock

6,970

Solution 1

The previous answer helped me write this fragment of bash script that handles Lock and Unlock session events for the current session. I use it to suspend browser processes when the session is locked and to resume them when it unlocks. Tested under Debian unstable (Xfce 4.12) Enjoy!

session=/org/freedesktop/login1/session/$XDG_SESSION_ID
iface=org.freedesktop.login1.Session
dbus-monitor --system "type=signal,path=$session,interface=$iface" 2>/dev/null |
 while read signal stamp sender arrow dest rest; do
  case "$rest" in
    *Lock)
      echo   LOCKED at $stamp
      pause $@
;;
    *Unlock)
      echo UNLOCKED at $stamp
      resume $@
;;  #unknown Session signal received
    *)
#      echo $signal $stamp $sender $arrow $dest $rest
  esac
done

Solution 2

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.

Solution 3

The following runs date whenever you lock or unlock by light-locker. However, I don't know how to know if it is locking or unlocking.

dbus-monitor --system "type='signal',sender='org.freedesktop.login1',path='/org/freedesktop/login1/seat/seat0',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'" | grep --line-buffered "ActiveSession" | while read line; do date; done

Reference: Launchpad bug report comment

Share:
6,970

Related videos on Youtube

jnovacho
Author by

jnovacho

Updated on September 18, 2022

Comments

  • jnovacho
    jnovacho almost 2 years

    I'd like to run a script if the XFCE session is locked and unlocked. Is there a way that I can intercept this and perform certain actions when the desktop is locked or unlocked?

    I have found following solutions:

    for Gnome - Run script on screen lock/unlock

    for xscreensaver - How do I run a script on unlock?

    But I'm using light-locker and no screen saver. I was trying to monitor DBUS but it doesn't seem the light-locker emits any signals.

    One option would be to modify xflock4 but that would help only with screen locking.

    Is there any way for light-locker?

    • doktor5000
      doktor5000 about 9 years
      By "I'd like to run a screen" do you mean what in particular? Do you want to run a screen session or do you only want to show some wallpaper? You might need to customize light-locker to achieve what you want. When you monitored dbus, did you also check for any signal emitted by libdm, as that's what light-locker uses [it's a part of LightDM].
    • jnovacho
      jnovacho about 9 years
      Sorry for confusion, that should've been script not screen.
    • doktor5000
      doktor5000 about 9 years
      Just like I thought. Seems to me you're taking the wrong approach. You should either extend the facility that calls light-locker (in your case xfce-power-manager together with upower) so that it will not only call xflock4 and then light-locker in advance, but make it more configurable. Best check some more documentation on xfce-power-manager, e.g. from LFS linuxfromscratch.org/blfs/view/cvs/xfce/… or upstream docs: docs.xfce.org/xfce/xfce4-power-manager/preferences and on systemd ...
    • doktor5000
      doktor5000 about 9 years
      Will try to make up an answer when I find some time to play with XFCE+light-locker myself, especially as the systemd inhibitor thing on power management is pretty badly documented, from an enduser perspective. Some more links for xfce-power-manager in the meantime for you: askubuntu.com/questions/407287/… + askubuntu.com/questions/580109/… + forum.xfce.org/viewtopic.php?id=6513
    • jnovacho
      jnovacho about 9 years
      Thanks for the links, I will look into it. It's possible I missed something on the DBUS as I was not sure what to look for. Your help is much appreciated.
    • doktor5000
      doktor5000 about 9 years
      Check the systemd inhibitor link. You might want to look for events for/from org.freedesktop.PowerManagement or related as that is where xfce4-power-manager registers: git.xfce.org/xfce/xfce4-power-manager/tree/src/… systemd-inhibit --list should show active inhibitors, for me under KDE e.g. currently networkmanager and powerdevil (KDE analogon to xfce4-power-manager)
  • Stephen Rauch
    Stephen Rauch over 7 years
    Welcome to Unix.stackexchange! I recommend you take the tour.
  • Paulo Marcel Coelho Aragão
    Paulo Marcel Coelho Aragão about 6 years
    I've managed to run the script (which I named quodr) under the user instance of systemd, which allowed me to remove the restart logic and logging from the script. So, I removed function log, LOGFILE and function kill_running, then created ~/.config/systemd/user/quodr.service: [Unit] Description=Refresh quodlibet after unlocking [Service] ExecStart=/home/paulo/bin/quodr Restart=always RestartSec=10 [Install] WantedBy=desktop.target and then enabled and started it: systemctl --user enable quodr.service systemctl --user start quodr.service