了解应用程序在可可mac OSX中是否处于非活动状态的最佳方法?

时间:2011-02-18 09:51:16

标签: objective-c cocoa macos

所以,我正在建立一个可以参加展览以供公众使用的程序,我有一个任务是为它做一个不活跃的状态。只需在屏幕上的文件夹中显示一些随机视频,如屏幕保护程序,但在应用程序中。

那么检查用户是否处于非活动状态的最佳和最佳方法是什么?

我在考虑的是某种全局计时器,它会在每个用户输入上重置,如果达到,可以说1分钟就进入非活动模式。有没有更好的方法?

6 个答案:

答案 0 :(得分:3)

您可以使用CGEventSourceSecondsSinceLastEventType

  

返回自Quartz事件的最后一个事件以来经过的时间   资源。

/*
 To get the elapsed time since the previous input event—keyboard, mouse, or tablet—specify kCGAnyInputEventType.
 */
- (CFTimeInterval)systemIdleTime
{       
    CFTimeInterval timeSinceLastEvent = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType);
    return timeSinceLastEvent;
}

答案 1 :(得分:2)

我正在扩大Parag Bafna的答案。在Qt中你可以做到

#include <ApplicationServices/ApplicationServices.h>

double MyClass::getIdleTime() {
    CFTimeInterval timeSinceLastEvent = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType);
    return timeSinceLastEvent;
}

您还必须将框架添加到.pro文件中:

QMAKE_LFLAGS += -F/System/Library/Frameworks/ApplicationServices.framework
LIBS += -framework ApplicationServices

该功能的文档是here

答案 2 :(得分:1)

这可能听起来像个愚蠢的问题;但为什么不设置一个屏幕保护程序,保险丝短?

如果您需要在用户离开时进行任何重置或清理,您可以收听名为@“com.apple.screensaver.didstart”的NSNotification。

修改:您还可以设置屏幕保护程序;等待它开始,然后在它启动时自己动手,在你显示自己的视频时停止屏幕保护程序;但是以正确的方式设置屏幕保护程序可能是一个好主意。

答案 3 :(得分:1)

查看this article,了解如何使用IOKit从IOHID读取用户空闲时间。

答案 4 :(得分:1)

我找到了一个使用HID管理器的解决方案,这似乎是在Cocoa中实现它的方法。 (还有另一种Carbon解决方案,但它不适用于64位OS X.)

引用Daniel Reese的Dan and Cheryl's Place博客:

#include <IOKit/IOKitLib.h>

/*
 Returns the number of seconds the machine has been idle or -1 on error.
 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;
            kern_return_t status;
            status = IORegistryEntryCreateCFProperties(entry,
                                                       &dict,
                                                       kCFAllocatorDefault, 0);
            if (status == KERN_SUCCESS)
            {
                CFNumberRef obj = CFDictionaryGetValue(dict,
                                                       CFSTR("HIDIdleTime"));
                if (obj) {
                    int64_t nanoseconds = 0;
                    if (CFNumberGetValue(obj,
                                         kCFNumberSInt64Type,
                                         &nanoseconds))
                    {
                        // Convert from nanoseconds to seconds.
                        idlesecs = (nanoseconds >> 30);
                    }
                }
                CFRelease(dict);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }
    return idlesecs;
}

代码稍作修改,使其符合80字符的stackoverflow限制。

答案 5 :(得分:1)

看看UKIdleTimer,也许这就是你要找的东西。