开发者

Best way to know if application is inactive in cocoa mac OSX?

开发者 https://www.devze.com 2023-02-12 01:49 出处:网络
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 scre

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 th开发者_高级运维ere any better ways?


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


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


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.


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号