views:

295

answers:

2

Is there an event fired when screensaver starts? Like for keychain locking:

OSStatus keychain_locked(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void *context){...}
A: 

While there is no Carbon event for this, you can get notified when the current application changes, and then check to see if the new application is the screen saver process.


// Register the event handler for when applications change
{
    EventTypeSpec es;
    es.eventClass = kEventClassApplication;
    es.eventKind = kEventAppFrontSwitched;
    InstallApplicationEventHandler(&appChanged, 1, &es, NULL, NULL);
}

OSStatus appChanged(EventHandlerCallRef nextHandler, EventRef anEvent, void* userData)
{
    ProcessSerialNumber psn;    
    GetEventParameter(anEvent, kEventParamProcessID, typeProcessSerialNumber,
                      NULL, sizeof(psn), NULL, &psn);

    // Determine process name
    char procName[255];
    {
        ProcessInfoRec pInfo;
        Str255 procName255;
        FSRef ref;

        pInfo.processInfoLength = sizeof(ProcessInfoRec);
        pInfo.processName = procName255;
        pInfo.processAppRef = &ref;
        GetProcessInformation(&psn, &pInfo);

        const unsigned int size = (unsigned int)procName255[0];
        memcpy(procName, procName255 + 1, size);
        procName[size] = '\0';
    }

    if(strcmp(procName, "ScreenSaverEngine") == 0)
    {
        NSLog(@"Found %s\n", procName);
    }

    return noErr;
}
nall
+3  A: 

Finally found it — the solution is to use NSDistributedNotificationCenter and observe folowing events

  • com.apple.screensaver.didstart
  • com.apple.screensaver.willstop
  • com.apple.screensaver.didstop
  • com.apple.screenIsLocked
  • com.apple.screenIsUnlocked

Like

[[NSDistributedNotificationCenter defaultCenter]
   addObserver:self
   selector:@selector(screensaverStarted:)
   name:@"com.apple.screensaver.didstart"
   object:nil];
tig