2011-12-19 4 views
2

上のユーザー操作の最後のインスタンス(エポックからの秒のように、好ましくは比較可能なデータ構造のいくつかの並べ替えでは。)私は、ユーザーが指定したマックと相互作用することを最後のインスタンスを検出しようとしているマック

この相互作用マウスの動き、アプリの対話などが含まれているはずですが、私はコンピュータがロックされているかスクリーンセーブ中であるかどうかを判断するつもりはありません。

答えて

4

あなたはこの機能を使用して最後のイベントからの秒数を取得することができます:

CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType); 

これはdoubleあるCFTimeIntervalを返します。

+0

起動デーモンでCGEventSourceSecondsSinceLastEventTypeを使用しないでください。 –

0

IOKitフレームワークを使用してください。見てくださいRHSystemIdleTimer

#import <Cocoa/Cocoa.h> 

@interface RHSystemIdleTimer : NSObject { 
    NSTimer *idleTimer, *continuingIdleTimer; 
    id delegate; 
    NSTimeInterval timeInterval; 
@private 
    mach_port_t masterPort; 
    io_iterator_t iter; 
    io_registry_entry_t curObj; 
} 
- (id)initSystemIdleTimerWithTimeInterval:(NSTimeInterval)ti; 
- (int)systemIdleTime; 
- (id)delegate; 
- (void)setDelegate:(id)receiver; 
- (void)invalidate; 
@end 

@interface RHSystemIdleTimer(Delegates) 
-(void)timerBeginsIdling:(id)sender; 
-(void)timerContinuesIdling:(id)sender; 
-(void)timerFinishedIdling:(id)sender; 
@end 

#import "RHSystemIdleTimer.h" 

@interface RHSystemIdleTimer(Private) 
- (void)checkIdleStatus; 
- (void)checkIfStillIdle; 
@end 

@implementation RHSystemIdleTimer 

#pragma mark Initilization/Dealloc 

- (id)initSystemIdleTimerWithTimeInterval:(NSTimeInterval)ti 
{ 
    self = [super init]; 
    if(self) { 

     IOMasterPort(MACH_PORT_NULL, &masterPort); 

     /* Get IOHIDSystem */ 
     IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); 
     if (iter == 0) { 
      NSLog(@"Error accessing IOHIDSystem\n"); 
     } 
     else { 
      curObj = IOIteratorNext(iter); 

      if (curObj == 0) { 
       NSLog(@"Iterator's empty!\n"); 
      } 
     } 

     timeInterval = ti;    
     idleTimer = [NSTimer scheduledTimerWithTimeInterval:ti 
                target:self 
                selector:@selector(checkIdleStatus) 
                userInfo:nil 
                repeats:NO]; 
    } 
    return self; 
} 

- (void) dealloc { 
    IOObjectRelease(curObj); 
    IOObjectRelease(iter); 
    [super dealloc]; 
} 

#pragma mark Accessors 

- (id)delegate 
{ 
    return delegate; 
} 

- (void)setDelegate:(id)receiver 
{ 
    delegate = receiver; 
} 

#pragma mark Private Methods 

- (void)checkIdleStatus 
{ 
    double idleTime = [self systemIdleTime]; 
    double timeLeft = timeInterval - idleTime; 
    if(timeLeft <= 0) { 

     if([delegate respondsToSelector:@selector(timerBeginsIdling:)]) { 
      [delegate timerBeginsIdling:self];   
     } 

     [NSTimer scheduledTimerWithTimeInterval:1.0 
             target:self 
             selector:@selector(checkIfStillIdle) 
             userInfo:nil 
             repeats:NO]; 

     if([delegate respondsToSelector:@selector(timerContinuesIdling:)]) { 
      continuingIdleTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval 
                    target:delegate 
                   selector:@selector(timerContinuesIdling:) 
                   userInfo:nil 
                    repeats:YES]; 
     }  
    } 
    else { 
     idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeLeft 
                target:self 
                selector:@selector(checkIdleStatus) 
                userInfo:nil 
                repeats:NO]; 
    } 
} 

- (void)checkIfStillIdle 
{ 
    double idleTime = [self systemIdleTime]; 
    if(idleTime <= 1.0) { 
     [continuingIdleTimer invalidate]; 

     if([delegate respondsToSelector:@selector(timerFinishedIdling:)]) { 
      [delegate timerFinishedIdling:self];    
     } 

     // reset; start checking for system idle time again 
     idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval 
             target:self 
             selector:@selector(checkIdleStatus) 
             userInfo:nil 
             repeats:NO]; 
    } 
    else { 
     [NSTimer scheduledTimerWithTimeInterval:1.0 
             target:self 
             selector:@selector(checkIfStillIdle) 
             userInfo:nil 
             repeats:NO]; 
    } 
} 

#pragma mark Public Methods 

- (void)invalidate 
{ 
    [idleTimer invalidate]; 
} 

- (int)systemIdleTime 
{  
    CFMutableDictionaryRef properties = 0; 
    CFTypeRef obj; 

    if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { 
     obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); 
     CFRetain(obj); 
    } else { 
     NSLog(@"Couldn't grab properties of system\n"); 
     obj = NULL; 
    } 

    uint64_t tHandle = 0; 
    if (obj) { 
     CFTypeID type = CFGetTypeID(obj); 

     if (type == CFDataGetTypeID()) { 
      CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(tHandle)), (UInt8*) &tHandle); 
     } 
     else if (type == CFNumberGetTypeID()) { 
      CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &tHandle); 
     } 
     else { 
      NSLog(@"%d: unsupported type\n", (int)type); 
     } 

     CFRelease(obj); 

     tHandle >>= 30; // essentially divides by 10^9 (nanoseconds) 
    } 
    else { 
     NSLog(@"Can't find idle time\n"); 
    } 

    CFRelease((CFTypeRef)properties);  
    return tHandle; 
} 

@end 
関連する問題