目标C:获取有关用户空闲状态的通知

Dav*_*vid 7 time objective-c python-idle

我的cocoa应用程序运行后台任务,我想在用户空闲时停止(没有键盘/鼠标输入),然后在用户再次激活时恢复.有没有办法注册空闲状态通知?

kpe*_*yua 6

有一个Carbon API会在调用一定时间后没有用户事件时发送通知EventLoopIdleTimer.Uli Kusterer为此写了一个Cocoa包装器(寻找UKIdleTimer).

如果你想要更低级别的东西,你可以通过计时器和CoreGraphics功能CGEventSourceSecondsSinceLastEventType(可用<CoreGraphics/CGEventSource.h>)的组合来实现你想要的行为.


Mir*_*sin 6

如果你无法链接到Carbon(即你想要编译x86_64位二进制),你可以在一个计时器中包装这个函数(它以秒的形式返回当前空闲时间的分辨率为双CFTimeInterval):

#include <IOKit/IOKitLib.h>

CFTimeInterval CFDateGetIdleTimeInterval() {
    mach_port_t port;
    io_iterator_t iter;
    CFTypeRef value = kCFNull;
    uint64_t idle = 0;
    CFMutableDictionaryRef properties = NULL;
    io_registry_entry_t entry;

    IOMasterPort(MACH_PORT_NULL, &port);
    IOServiceGetMatchingServices(port, IOServiceMatching("IOHIDSystem"), &iter);
    if (iter) {
        if ((entry = IOIteratorNext(iter))) {
            if (IORegistryEntryCreateCFProperties(entry, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties) {
                if (CFDictionaryGetValueIfPresent(properties, CFSTR("HIDIdleTime"), &value)) {
                    if (CFGetTypeID(value) == CFDataGetTypeID()) {
                        CFDataGetBytes(value, CFRangeMake(0, sizeof(idle)), (UInt8 *) &idle);
                    } else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
                        CFNumberGetValue(value, kCFNumberSInt64Type, &idle);
                    }
                }
                CFRelease(properties);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }

    return idle / 1000000000.0;
}
Run Code Online (Sandbox Code Playgroud)

您需要将代码链接到 IOKit.framework