2

为了在 OS X Lion 上启动屏幕保护程序,我使用了一个系统范围的键盘快捷键,它可以立即启动屏幕保护程序,使用一个简单的 applescript:

tell application "ScreenSaverEngine" to launch

尽管这在大多数情况下都可以完美运行,但是当鼠标恰好在调用脚本时移动时,我遇到了一个奇怪的问题。然后,ScreenSaverEngine.app 被加载并且桌面被锁定,但是 ScreenSaverEngine UI 没有出现。相反,桌面仍然可见,但无法将焦点设置在其他应用程序或 UI 控件上;桌面会话基本上被锁定。

“解锁”桌面的唯一方法是强制将焦点设置在 Activity Monitor 应用程序上(通过按住 Ctrl 键单击其停靠图标并选择 Show All Windows),然后终止 ScreenSaverEngine 进程。

通过从终端启动 ScreenSaverEngine 可以轻松重现相同的行为:

/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine

并在按下 Enter 键的同时主动移动鼠标光标。

有谁知道一种可以用来以编程方式启动屏幕保护程序的方法,并且不会遇到这个问题?

注意:我知道还有其他选项可以锁定屏幕(快速用户切换、钥匙串锁定和热角),但我对这些解决方案不感兴趣,我需要一种以编程方式启动屏幕保护程序的方法。

4

1 回答 1

0

我自己在谷歌的深处找到了答案。使用私有 ScreenSaver.framework 中未记录的 ScreenSaverController 类来启动屏幕保护程序按预期工作。

我使用以下标题:

#import <Foundation/Foundation.h>

@interface ScreenSaverController : NSObject
+ controller;
@end

@protocol ScreenSaverControl
- (BOOL) screenSaverIsRunning;
- (BOOL) screenSaverCanRun;
- (void) setScreenSaverCanRun:(BOOL)fp8;
- (void) screenSaverStartNow;
- (void) screenSaverStopNow;
- (void) restartForUser:(id)fp8;
- (double) screenSaverTimeRemaining;
- (void) screenSaverDidFade;
- (BOOL) screenSaverIsRunningInBackground;
- (void) screenSaverDidFadeInBackground:(BOOL)fp8 
                                  psnHi:(unsigned int)fp12 
                                 psnLow:(unsigned int)fp16;
@end

并将 ScreenSaver.framework 链接到我的项目。启动屏幕保护程序非常简单:

[[ScreenSaverController controller] screenSaverStartNow];

当屏幕保护程序以这种方式启动时,我在问题中描述的行为无法重现。如果调用此方法时鼠标主动移动,屏幕快速闪烁,屏幕保护程序立即返回(不锁定桌面)。

适用于 10.6.8 和 10.7.4。

免责声明:请谨慎使用 Apple 框架中未记录的类,因为它们不受支持,并且功能可能会在 OS X 的未来版本中中断(考虑弱链接)。此外,它还会取消您的应用在 App Store 中的资格。

于 2012-07-24T08:12:40.060 回答