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

Posted

技术标签:

【中文标题】了解应用程序在 cocoa mac OSX 中是不是处于非活动状态的最佳方法?【英文标题】:Best way to know if application is inactive in cocoa mac OSX?了解应用程序在 cocoa mac OSX 中是否处于非活动状态的最佳方法? 【发布时间】:2011-02-18 09:51:16 【问题描述】:

所以,我正在构建一个程序,该程序将在展览上供公众使用,我的任务是为其设置一个非活动状态。只需在屏幕上的文件夹中显示一些随机视频,就像屏幕保护程序一样,但在应用程序中。

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

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

【问题讨论】:

看看this article 介绍了使用 IOKit 从 IOHID 读取用户空闲时间。 【参考方案1】:

你可以使用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;

【讨论】:

【参考方案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

【讨论】:

【参考方案3】:

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

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

#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 个字符的限制。

【讨论】:

【参考方案4】:

这听起来像是一个愚蠢的问题;但是为什么不直接设置一个屏幕保护程序呢?

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

编辑:您也可以设置屏幕保护程序;等待它启动,然后在它启动时做你自己的事情,当你显示自己的视频时停止屏幕保护程序;但是以正确的方式设置屏幕保护程序可能是个好主意。

【讨论】:

如果有任何具有我正在寻找的功能的优秀屏幕保护程序必须在我的应用程序等的视频上添加一些自定义信息,那就太好了:( 无论如何,您都必须构建该功能;还不如让它成为一个屏幕保护程序。制作屏幕保护程序并不难。至少在我所见的范围内没有。【参考方案5】:

看看UKIdleTimer,也许就是你要找的。​​p>

【讨论】:

以上是关于了解应用程序在 cocoa mac OSX 中是不是处于非活动状态的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 Cocoa Mac OSX 中设置 FirstResponder 的问题

Objective C - 创建 PDF (Mac OSX / Cocoa)

在 Swift、Cocoa、Mac OSX 中将 EXIF 数据设置为 NSImage

就像在我的 Mac OSX Cocoa 应用程序中在 Microsoft Word 中一样创建字体菜单

Cocoa osx PDFView NSPrintOperation PrintPanel 不显示页面预览

Cocoa - 如何检测泛在容器中的变化