OSX: check if the screen is locked

Viewed 10733

Is there any way to check if screen is locked in shell or applescript? Not just check if screensaver is running, but screen is locked by energy saver settings or by pressing ⌃⇧⏏ (shift+control+eject).

Thank you in advance.

3 Answers

The answer from @LevB is great but with the advent of Python "deprecation" in macOS (which has not yet seen its removal as of Big Sur) I wondered if there was another way to get CGSSessionScreenIsLocked, Applecare Enterprise Support pointed me to ioreg where these CoreGraphics Session values also live

Below are a couple shell function one-liners, in the shell style they return zero (0) in the affirmative (success) and non-zero (1) in the negative so they can be used as expected in if statements.

function screenIsLocked { [ "$(/usr/libexec/PlistBuddy -c "print :IOConsoleUsers:0:CGSSessionScreenIsLocked" /dev/stdin 2>/dev/null <<< "$(ioreg -n Root -d1 -a)")" = "true" ] && return 0 || return 1; }
function screenIsUnlocked { [ "$(/usr/libexec/PlistBuddy -c "print :IOConsoleUsers:0:CGSSessionScreenIsLocked" /dev/stdin 2>/dev/null <<< "$(ioreg -n Root -d1 -a)")" != "true" ] && return 0 || return 1; }

Note these keys only exist when the screen is locked: kCGSSessionSecureInputPID, CGSSessionScreenLockedTime, CGSSessionScreenIsLocked. When the screen is unlocked CGSSessionScreenIsLocked is not present, thus the != "true" comparison, since it will never be "false"

Example usage (since the simplicity of if evaluating exit codes is sometimes not realized):

#!/bin/sh

function screenIsLocked { [ "$(/usr/libexec/PlistBuddy -c "print :IOConsoleUsers:0:CGSSessionScreenIsLocked" /dev/stdin 2>/dev/null <<< "$(ioreg -n Root -d1 -a)")" = "true" ] && return 0 || return 1; }
function screenIsUnlocked { [ "$(/usr/libexec/PlistBuddy -c "print :IOConsoleUsers:0:CGSSessionScreenIsLocked" /dev/stdin 2>/dev/null <<< "$(ioreg -n Root -d1 -a)")" != "true" ] && return 0 || return 1; }

if screenIsLocked; then
    echo "Screen locked"
fi

if screenIsUnlocked; then
    echo "Screen unlocked"
fi

if ! screenIsLocked; then
    echo "Screen unlocked (inverse logic)"
fi

if ! screenIsUnlocked; then
    echo "Screen locked (inverse logic)"
fi

With jdk9 you can use

java.awt.Desktop



Desktop tempDesktop = Desktop.getDesktop();
        tempDesktop.addAppEventListener(new UserSessionListener() {

            @Override
            public void userSessionDeactivated(UserSessionEvent aE) {
                LOG.info("Desktop:userSessionDeactivated Reason=" + aE.getReason() + " Source=" + aE.getSource());
                // Windows Key L: 
                // Tue Aug 31 11:22:49 CEST 2021:info:MainController:userSessionDeactivated Reason=LOCK

                // Close Lid:
                // Tue Aug 31 11:24:38 CEST 2021:info:MainController:userSessionDeactivated Reason=LOCK
                // Tue Aug 31 11:24:39 CEST 2021:info:MainController:systemAboutToSleep Source=java.awt.Desktop@741f67cd

                ptcUserStatus = PtcUserStatus.AWAY;

            }

            @Override
            public void userSessionActivated(UserSessionEvent aE) {
                LOG.info("Desktop:userSessionActivated Reason=" + aE.getReason() + " Source=" + aE.getSource());
                // Logon after Windows Key L
                // Tue Aug 31 11:22:53 CEST 2021:info:MainController:userSessionActivated Reason=LOCK

                // Open Lid:
                // Tue Aug 31 11:24:56 CEST 2021:info:MainController:systemAwoke Source=java.awt.Desktop@741f67cd
                // Tue Aug 31 11:25:06 CEST 2021:info:MainController:userSessionActivated Reason=LOCK
                ptcUserStatus = PtcUserStatus.BACK;
            }
        });
Related