By Naftuli Kay


2012-01-03 02:14:50 8 Comments

I'd like to run a screen if the Gnome 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?

9 comments

@user2777461 2019-11-08 13:55:56

this may not be the cleanest solution but it works for me when dbus-monitor ... does not:

gdbus monitor -y -d org.freedesktop.login1 |\
 grep --line-buffered -i "LockedHint" |\
 sed -uE 's/.*LockedHint.*<(.*)>.*/\1/g'

Should return stream of lines with strings 'true' or 'false'

Using: Fedora release 30 (Thirty)

@Jeff Schaller 2019-11-08 14:34:50

appears to be an extension of this answer

@cprn 2017-06-01 18:25:12

Expanding on already given answer.

If you try to run a script from inside a screen or tmux session, you'll need to find the correct $DBUS_SESSION_BUS_ADDRESS first and pass it as an argument for dbus-monitor instead of --session. Also if you're running it as a daemon you should make sure only one instance is running at a time (e.g. with a lock file) and that the script cleans up after itself with trap. The following example will work as a daemon in most current Gnome environments (tested on Ubuntu GNOME 16.04):

#!/bin/bash
set -o nounset                # good practice, exit if unset variable used

pidfile=/tmp/lastauth.pid     # lock file path
logfile=/tmp/lastauth.log     # log file path

cleanup() {                   # when cleaning up:
    rm -f $pidfile            # * remove the lock file
    trap - INT TERM EXIT      # * reset kernel signal catching
    exit                      # * stop the daemon
}

log() {                       # simple logging format example
    echo $(date +%Y-%m-%d\ %X) -- $USER -- "[email protected]" >> $logfile
}

if [ -e "$pidfile" ]; then    # if lock file exists, exit
    log $0 already running...
    exit
fi

trap cleanup INT TERM EXIT    # call cleanup() if e.g. killed

log daemon started...

echo $$ > $pidfile            # create lock file with own PID inside

# usually `dbus-daemon` address can be guessed (`-s` returns 1st PID found)
export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pidof -s dbus-daemon)/environ)

expr='type=signal,interface=org.gnome.ScreenSaver' # DBus watch expression here

dbus-monitor --address $DBUS_SESSION_BUS_ADDRESS "$expr" | \ 
    while read line; do
        case "$line" in
            *"boolean true"*) log session locked;;
            *"boolean false"*) log session unlocked;;
        esac
    done

cleanup # let's not leave orphaned lock file when the loop ends (e.g. dbus dies)

If this doesn't work for you, it's probably because:

  1. you don't use Gnome - check other answers for better DBus watch expression.
  2. you run multiple DBus lines - check details on how to make PID finding deterministic.

@Naftuli Kay 2017-06-02 05:10:07

This actually answers a different question I had for dynamically discovering the DBus session information given a user account, which I have solved here. Thanks for your contribution here!

@cprn 2017-06-02 09:53:00

Thanks. I'll link your solution in the answer for further reading.

@Oleg V. Volkov 2018-11-14 19:53:41

upstart session jobs support desktop-lock and desktop-unlock events in start on stanza. Just create a job .conf for your user with relevant triggers and commands to call under $XDG_CONFIG_HOME/upstart/ or $HOME/.config/upstart like example below:

description "some job description"
start on desktop-lock
script
        /path/to/your/executable
end script

@Matthew 2018-06-10 23:33:25

Nowadays I think it's better to listen to the LockedHint rather than screensaver messages. That way you're not tied to a screensaver implementation.

Here's a simple script to do that:

gdbus monitor -y -d org.freedesktop.login1 | grep LockedHint

Gives this:

/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <true>}, @as [])
/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <false>}, @as [])

@Bob 2017-04-27 07:55:00

If you're on Kubuntu or using KDE / Plasma as your Desktop Environment, you have to listen for the interface org.freedesktop.ScreenSaver, so the script for listening to that event would look like this:

dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" |
  while read x; do
    case "$x" in 
      *"boolean true"*) echo SCREEN_LOCKED;;
      *"boolean false"*) echo SCREEN_UNLOCKED;;  
    esac
  done

@xenoid 2019-04-03 12:40:09

If you use KDE/Plasma you can use the Plasma Desktop settings to execute scripts on notifications... Personalization>Notifications>Notifications>Screensaver.

@Ankur S 2019-09-19 13:32:05

thanks @xenoid ! KDE is such a personalizable de that you never have to fiddle with these things. its as if they anticipate what I need

@peoro 2012-01-03 02:57:11

Gnome-screensaver emits some signals on dbus when something happens.

Here the documentation (with some examples).

You could write a scripts that runs:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'"

and that does what you need anytime dbus-monitor prints a line about the screen being locked/unlocked.


Here a bash command to do what you need:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" |
  while read x; do
    case "$x" in 
      *"boolean true"*) echo SCREEN_LOCKED;;
      *"boolean false"*) echo SCREEN_UNLOCKED;;  
    esac
  done

Just replace echo SCREEN_LOCKED and echo SCREEN_UNLOCKED with what you need.

@Nikhil Mulley 2012-01-03 05:13:22

Hi @peoro, That makes me think you can unlock or lock gnome screen/session from a scripted program, worth doing some ssh tricks about it ;-)

@peoro 2012-01-03 05:18:53

@Nikhil: to do that you don't need to play around with dbus: gnome-screensaver-command is already there. Passing -a to gnome-screensaver-command you'll lock the screen, while you'll unlock it with -d. Anyway most gnome apps use dbus extensively, so you'll be able to do many amazing things with it.

@Sander 2012-01-04 16:13:07

@peoro Thanks great, very helpful! Can I also run this as some sort of daemon? When I enter this in the terminal now, it has to stay open to monitor the dbus for that case. I would like to execute this command at login and then it can be active during the entire session.

@Aquarius Power 2014-08-02 02:18:20

I think things may have changed now in 2014? as the output doesnt change if the screen was only locked, it only shows something when it gets blanked and is very different from here :(, I created this question askubuntu.com/questions/505681/…, do you believe there is still some way to do that? thx!

@Starx 2016-11-01 13:03:36

How to run that script that it catches the lock event? Kinda like a watcher.

@hanzo2001 2017-11-29 11:30:31

Does anybody know how or where to hook this script to start listening on first login?

@Artemy Tregubenko 2016-10-09 12:09:13

Ubuntu 16.04: ozma’s solution did not work for me, however this one did:

dbus-monitor --session "type=signal,interface=com.canonical.Unity.Session,member=Unlocked" | 
  while read MSG; do
    LOCK_STAT=`echo $MSG | awk '{print $NF}'`
    if [[ "$LOCK_STAT" == "member=Unlocked" ]]; then
        echo "was unlocked"
    fi
  done

@cprn 2017-06-01 10:03:17

It might work on Unity but question was in regards to Gnome.

@ozma 2016-07-26 17:02:22

this is what worked for me in ubuntu 16.04

dbus-monitor --session "type=signal,interface=org.gnome.ScreenSaver" | 
  while read MSG; do
    LOCK_STAT=`echo $MSG | grep boolean | awk '{print $2}'`
    if [[ "$LOCK_STAT" == "true" ]]; then
        echo "was locked"
    else
        echo "was un-locked"
    fi
  done

@Starx 2016-11-01 13:12:33

This didn't work for me. As it finished executing and does not listen to the state changed.

@ozma 2016-11-01 14:06:29

which screen saver are you using? gnome or xscreensaver? which flavor ubuntu, xubuntu, kubuntu etc. which version (it was tested on 16.04)

@Starx 2016-11-02 09:25:03

ubuntu gnome 16.04

@Luv Agarwal 2015-06-24 14:38:24

In ubuntu 14.04 the DBus event for screen lock unlock has changed and the new script for binding to screen lock and unlock events looks like the following

dbus-monitor --session "type='signal',interface='com.ubuntu.Upstart0_6'" | \
(
  while true; do
    read X
    if echo $X | grep "desktop-lock" &> /dev/null; then
      SCREEN_LOCKED;
    elif echo $X | grep "desktop-unlock" &> /dev/null; then
      SCREEN_UNLOCKED;
    fi
  done
)

@Ray Foss 2016-04-30 21:49:29

ideas on how to make this work on fedora 23?

@Jacob Vlijm 2016-11-29 06:43:18

Works fine on 16.04 as well

@WinEunuuchs2Unix 2016-12-08 00:44:40

@JacobVlijm Thanks for testing this and green-lighting it for me to use tonight :)

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] CentOS 7 GNOME lock screen although all settings say otherwise

2 Answered Questions

1 Answered Questions

[SOLVED] GDM Can't unlock screen

  • 2018-10-15 15:37:16
  • patrykbajos
  • 456 View
  • 3 Score
  • 1 Answer
  • Tags:   gnome manjaro gdm

1 Answered Questions

1 Answered Questions

Sponsored Content