Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OSX: check if the screen is locked

Tags:

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.

like image 522
LevB Avatar asked Jul 16 '12 13:07

LevB


People also ask

How do you check Lock Screen time on Mac?

Use the Options pane of Screen Time preferences to choose options and to turn Screen Time on or off. To change these preferences on your Mac, choose Apple menu > System Preferences, click Screen Time , then click Options in the sidebar.

How do I stop my Mac screen from locking?

All replies. Turn it off in the Energy Saver and Security & Privacy panes of System Preferences.

How do I stop my Mac from locking after inactivity?

From the Apple menu, choose System Preferences. Click Desktop & Screen Saver. Click Screen Saver, and then use the slider to choose 15 minutes (or less).

How do I manually lock my Mac screen?

Using keyboard shortcuts You can easily lock your Mac from your keyboard: Press Control + Command + Q: This shortcut will take you directly to the lock screen.


1 Answers

First, there's a bit of confusion in your question. Both Shift+Control+Eject and Energy Saver put the screens to sleep, which isn't the same thing as locking them. Depending on your other settings, this may also entail locking the screen, but that's a separate issue. IIRC, on Lion, by default, neither one will ever lock the screen—but if you leave the screen asleep for longer than the time set in Security & Privacy, that will lock it.

Anyway, the API CGSessionCopyCurrentDictionary allows you to get information about both screen sleep and screen lock, for your GUI session. If you don't have a GUI session (e.g., because you're running in an ssh shell), or your session doesn't own the console (e.g., because someone has fast-user-switched you out), you won't be able to get this information, but you will at least be able to detect those cases.

This is the only mechanism I know of that works for all OS's from 10.5 (actually 10.3) to 10.8 (but that doesn't mean it's the only one there actually is…).

There's no direct way to call this from bash or AppleScript. However, you can use your favorite bridge (PyObjC, MacRuby, ASOC, etc.) to call it indirectly. Here's an example using Python:

#!/usr/bin/python import Quartz d = Quartz.CGSessionCopyCurrentDictionary() print d 

Here's how to interpret the response:

  • If you get nothing back, then you don't have a UI session.
  • If the dictionary has kCGSSessionOnConsoleKey = 0, or not present, either your GUI session doesn't own the console, or the console's screens are asleep.
  • If the dictionary has CGSSessionScreenIsLocked = 1, the screens are locked.

The one problem case is where kCGSSessionOnConsoleKey is 0 (or missing) and CGSSessionScreenIsLocked is 1. In that case, either you've put the screens to sleep and locked them, or someone else has taken the console and locked the screens (with or without putting them to sleep). And I'm not sure if there's a way to distinguish between these cases. But if you're looking for "don't try to display a dialog because the user will have to unlock the screen first", both of those cases mean "don't display a dialog".

So, this should give you what you want:

#!/usr/bin/python import sys import Quartz d=Quartz.CGSessionCopyCurrentDictionary() sys.exit(d and           d.get("CGSSessionScreenIsLocked", 0) == 0 and           d.get("kCGSSessionOnConsoleKey", 0) == 1) 

Or, turning it into a one-liner you can put directly in a shell script:

python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); sys.exit(d and d.get("CGSSessionScreenIsLocked", 0) == 0 and d.get("kCGSSessionOnConsoleKey", 0) == 1)' 

Now, what if you've ssh'd into a Mac, and you're also currently logged into that Mac's GUI console (as the same user)? In that case, your ssh login session can communicate with the console login session in exactly the same way that a local Terminal login session would. So, CGSessionCopyCurrentDictionary is going to get the same values.

The bootstrap server that mediates that connection will apply some restrictions (e.g., security authorize -u foo should work from the Terminal but not over ssh), but those aren't fully documented, and change from version to version, so that's probably not something you want to rely on. Instead, you want to actually read your login session information

If you want to go further with this, start with reading Multiple User Environments Programming Topics. But some of the information isn't really documented anywhere (e.g., how the Mach-level sessions referenced by SessionGetInfo and the BSD-level sessions referenced by utmpx are tied together). Many of the relevant tools and libraries are open source, which may help. Even if reading up on all of that doesn't tell you how to do what you want, it will tell you exactly what you want, and the right terms to use to search and ask questions, which may be good enough.

like image 133
abarnert Avatar answered Nov 14 '22 04:11

abarnert