Skip to content

June 28, 2010

How to Check the System Idle Time Using Cocoa

by Dan

UPDATE: Aleksandar Sabo wrote a brief explanation of how this code works.

There is sample code on the Internet for programmatically checking the system idle time using IOKit and Cocoa (see here, for example). However, most of the examples seem overly long (see Paul Graham’s Succinctness is Power). The code below works in Tiger/10.4 and later and is about as concise as I can make it while still handling errors properly.

#include <IOKit/IOKitLib.h>

/**
 Returns the number of seconds the machine has been idle or -1 if an error occurs.
 The code is compatible with Tiger/10.4 and later (but not iOS).
 */
int64_t SystemIdleTime(void) {
    int64_t idlesecs = -1;
    io_iterator_t iter = 0;
    if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) {
        io_registry_entry_t entry = IOIteratorNext(iter);
        if (entry) {
            CFMutableDictionaryRef dict = NULL;
            if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS) {
                CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
                if (obj) {
                    int64_t nanoseconds = 0;
                    if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) {
                        idlesecs = (nanoseconds >> 30); // Divide by 10^9 to convert from nanoseconds to seconds.
                    }
                }
                CFRelease(dict);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }
    return idlesecs;
}    

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.

Comments are closed.