11

I know that there is some way to get the system idle time with the IOKit framework on OS X, but I want to know if there's notifications available.

I can create a timer to check if the idle time is more than x, and that's fine. It doesn't matter if I detect the idle mode a few seconds later.

The problem is to detect when the Mac is not idle anymore. I want my app to show a notification as soon as possible, not a few seconds later.

Is there a way to have a notification for that? (iChat seems to have one)

pppery
  • 3,731
  • 22
  • 33
  • 46
gcamp
  • 14,622
  • 4
  • 54
  • 85
  • 3
    I’ve tested `NSWorkspaceScreensDidWakeNotification` and it works provided the definition of returning from idle is the same as waking the display. Other than that, you might have to install an event tap to detect mouse/keyboard events, interpreting them as returning from idle. –  Jun 20 '11 at 23:16
  • 1
    @Bavarious make this an answer. – batman Jun 23 '11 at 23:56
  • 1
    I don't know if there's a difference between Cocoa and Objective C, but the answer to [Objective C: Get notifications about a user's idle state](http://stackoverflow.com/questions/4643579/objective-c-get-notifications-about-a-users-idle-state) might help. – Bill the Lizard Jul 20 '11 at 15:49

2 Answers2

9

This is from http://developer.apple.com/library/mac/#qa/qa1340/_index.html (from Bill the Lizard comment)

- (void) receiveSleepNote: (NSNotification*) note
{
    NSLog(@"receiveSleepNote: %@", [note name]);
}

- (void) receiveWakeNote: (NSNotification*) note
{
    NSLog(@"receiveWakeNote: %@", [note name]);
}

- (void) fileNotifications
{
    //These notifications are filed on NSWorkspace's notification center, not the default 
    // notification center. You will not receive sleep/wake notifications if you file 
    //with the default notification center.
    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self 
            selector: @selector(receiveSleepNote:) 
            name: NSWorkspaceWillSleepNotification object: NULL];

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self 
            selector: @selector(receiveWakeNote:) 
            name: NSWorkspaceDidWakeNotification object: NULL];
}
conrad10781
  • 2,223
  • 19
  • 17
Paulo Casaretto
  • 967
  • 10
  • 33
1
NSTimeInterval GetIdleTimeInterval() {

    io_iterator_t iter = 0;
    int64_t nanoseconds = 0;

    if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) {
        io_registry_entry_t entry = IOIteratorNext(iter);
        if (entry) {
            CFMutableDictionaryRef dict;
            if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS) {
                CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
                if (obj)
                    CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds);
                CFRelease(dict);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }

    return (double)nanoseconds / 1000000000.0;
}
Mike Glukhov
  • 1,758
  • 19
  • 18