Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
591 views
in Technique[技术] by (71.8m points)

macos - OSX: check if the screen is locked

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...