知道应用程序在 cocoa mac OSX 中是否处于非活动状态的最佳方法?

发布于 2024-10-18 01:16:29 字数 189 浏览 1 评论 0原文

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

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

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

So, i am building a program that will stand on a exhibition for public usage, and i got a task to make a inactive state for it. Just display some random videos from a folder on the screen, like a screensaver but in the application.

So what is the best and proper way of checking if the user is inactive?

What i am thinking about is some kind of global timer that gets reset on every user input and if it reaches lets say 1 minute it goes into inactive mode. Are there any better ways?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月下凄凉 2024-10-25 01:16:29

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

You can use CGEventSourceSecondsSinceLastEventType

Returns the elapsed time since the last event for a Quartz event
source.

/*
 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;
}
无力看清 2024-10-25 01:16:29

我正在扩展 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

该函数的文档是 此处

I'm expanding on Parag Bafna's answer. In Qt you can do

#include <ApplicationServices/ApplicationServices.h>

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

You also have to add the framework to your .pro file:

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

The documentation of the function is here

眼泪淡了忧伤 2024-10-25 01:16:29

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

Dan 和 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;
}

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

I've found a solution that uses the HID manager, this seems to be the way to do it in Cocoa. (There's another solution for Carbon, but it doesn't work for 64bit OS X.)

Citing Daniel Reese on the Dan and Cheryl's Place blog:

#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;
}

The code has been slightly modified, to make it fit into the 80-character limit of stackoverflow.

ㄖ落Θ余辉 2024-10-25 01:16:29

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

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

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

This might sound like a silly question; but why not just set up a screensaver, with a short fuse?

You can listen for the NSNotification named @"com.apple.screensaver.didstart" if you need to do any resets or cleanups when the user wanders away.

Edit: You could also set up the screen saver; wait for it to fire, and then do your own thing when it starts, stopping the screen saver when you display your own videos; but setting up a screen saver the proper way is probably a good idea.

ぽ尐不点ル 2024-10-25 01:16:29

看看 UKIdleTimer,也许这就是您正在寻找的。

Take a look at UKIdleTimer, maybe it's what you're looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文