unity - how to detect if the screen is locked?

5,416

Solution 1

Aquarius Power's answer seems to work quite well. Here are some additions I might make to his solution.

Only querying lock state

If you simply need a one-liner to query the lock state, this should evaluate to true if locked and false if unlocked.

isLocked=$(gdbus call -e -d com.canonical.Unity -o /com/canonical/Unity/Session -m com.canonical.Unity.Session.IsLocked | grep -ioP "(true)|(false)")

Querying lock state and track time since last change in state

Now if you need to keep track of how long the screen has been locked you might want to take a different approach.

#!/bin/bash
# To implement this, you can put this at the top of a bash script or you can run
# it the subshell in a separate process and pull the functions into other scripts.

# We need a file to keep track of variable inside subshell the file will contain
# two elements, the state and timestamp of time changed, separated by a tab.
# A timestamp of 0 indicates that the state has not changed since we started
# polling for changes and therefore, the time lapsed in the current state is
# unknown.
vars="/tmp/lock-state"

# start watching the screen lock state
(
    # set the initial value for lock state
    [ "$(gdbus call -e -d com.canonical.Unity -o /com/canonical/Unity/Session -m com.canonical.Unity.Session.IsLocked | grep -ioP "(true)|(false)")" == "true" ] && state="locked" || state="unlocked"
    printf "%s\t%d" $state 0 > "$vars"
    
    # start watching changes in state
    gdbus monitor -e -d com.canonical.Unity -o /com/canonical/Unity/Session | while read line
    do 
        state=$(grep -ioP "((un)?locked)" <<< "$line")
        # If the line read denotes a change in state, save it to a file with timestamp for access outside this subshell
        [ "$state" != "" ] && printf "%s\t%d" ${state,,} $(date +%s)> "$vars"
    done
) & # don't wait for this subshell to finish

# Get the current state from the vars exported in the subshell
function getState {
    echo $(cut -f1 "$vars")
}

# Get the time in seconds that has passed since the state last changed
function getSecondsElapsed {
    if [ $(cut -f2 "$vars") -ne 0 ]; then
        echo $(($(date +%s)-$(cut -f2 "$vars")))
    else
        echo "unknown"
    fi
}

Essentially, this script watches for changes in the lock state of the screen. When changes take place, the time and state is dumped to a file. You can read this file manually if you like or use the functions I wrote.

If you want a timestamp rather than the number of seconds, try:

date -ud @$(getSecondsElapsed) | grep -oP "(\d{2}:){2}\d{2}"

Don't forget the -u switch which forces the date program to ignore your timezone.

Solution 2

the screen is actually locked by Unity, and, we need to use gdbus

gdbus monitor -e -d com.canonical.Unity -o /com/canonical/Unity/Session

this will show when it got locked like:

/com/canonical/Unity/Session: com.canonical.Unity.Session.LockRequested ()
/com/canonical/Unity/Session: com.canonical.Unity.Session.Locked ()
/com/canonical/Unity/Session: com.canonical.Unity.Session.UnlockRequested ()
/com/canonical/Unity/Session: com.canonical.Unity.Session.Unlocked ()

Solution 3

I had a similar question here

and the help I got was similar to what Aquarius Power said before, except that it was included in a bash scrip daemon, that can run in the background.. I found it very helpful. so, have a look at my Question, and answer, and see if this helps you also.

Share:
5,416
Aquarius Power
Author by

Aquarius Power

Updated on September 18, 2022

Comments

  • Aquarius Power
    Aquarius Power over 1 year

    both of these only work after the screen that was locked gets blanked; but they sometimes fail also, when for any reason the screen doesnt blanks...

    gnome-screensaver-command --query
    gnome-screensaver-command --time
    

    I tried with qdbus also:

    qdbus org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.GetActiveTime
    

    but it equally failed.

    I just found that who actually locks the screen is Unity!

    qdbus com.canonical.Unity /com/canonical/Unity/Session com.canonical.Unity.Session.Lock
    

    Related questions:
    https://unix.stackexchange.com/questions/28181/run-script-on-screen-lock-unlock https://unix.stackexchange.com/questions/80143/how-to-create-a-daemon-which-would-be-listening-to-dbus-and-fire-script-on-messa

  • Noitidart
    Noitidart over 9 years
    I'm not very familiar, but how to do this without the monitoring? like just query'ing?
  • Aquarius Power
    Aquarius Power over 9 years
    the only option I found was to keep it monitoring (may be there is a way to just query, but I couldnt find despite I tried), I guess it is because the moment the screen is locked is not stored anyewhere, so the monitor would be the only way to show when it happens.
  • Aquarius Power
    Aquarius Power over 9 years
    I mean, try too, if you find, tell me, or add an answer :D
  • Noitidart
    Noitidart over 9 years
    Ah haha ok ill try to find it im not good with linux im a windows guy :P im just coding some cross os stuff so searching the internet.
  • Aquarius Power
    Aquarius Power about 7 years
  • Noitidart
    Noitidart about 7 years
    Thank you so so much @AquariusPower for the ping! This was still an issue for me!
  • Aquarius Power
    Aquarius Power about 7 years
    finally could test it, thx! thats why I like to not accept my own answer when I answer myself so better things may come out later :)
  • wjandrea
    wjandrea over 5 years
    For grep -ioP "(true)|(false)", this also works: grep -oE "true|false"