Macos Mac上用户交互的最后一个实例
我正在尝试检测用户与给定Mac交互的最后一个实例(最好是在某种类似的数据结构中,比如从纪元开始的几秒钟)Macos Mac上用户交互的最后一个实例,macos,cocoa,user-interaction,Macos,Cocoa,User Interaction,我正在尝试检测用户与给定Mac交互的最后一个实例(最好是在某种类似的数据结构中,比如从纪元开始的几秒钟) 此交互应包括键入、鼠标移动、应用程序交互等。但是,我不想确定计算机是否锁定或屏幕保存,因为这些状态取决于用户偏好。您可以使用此功能获取自上次事件以来的秒数: CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType); 这将返回一个CFTimeInterval
此交互应包括键入、鼠标移动、应用程序交互等。但是,我不想确定计算机是否锁定或屏幕保存,因为这些状态取决于用户偏好。您可以使用此功能获取自上次事件以来的秒数:
CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType);
这将返回一个
CFTimeInterval
,它是一个double
UseIOKit
框架。看看
#导入
@接口RHSystemIdleTimer:NSObject{
n定时器*空闲定时器,*持续空闲定时器;
id代表;
NSTimeInterval时间间隔;
@私人的
mach_port_t masterPort;
io迭代器iter;
io_注册表_条目_t curObj;
}
-(id)initSystemIdleTimerWithTimeInterval:(NSTimeInterval)ti;
-(int)系统空闲时间;
-(id)代表;
-(无效)setDelegate:(id)接收者;
-(无效)无效;
@结束
@接口RHSystemIdleTimer(代理)
-(void)TimerBeginsilling:(id)发送方;
-(void)timercontinuesiling:(id)发送方;
-(无效)TimerFinishedilling:(id)发送方;
@结束
#导入“RHSystemIdleTimer.h”
@接口RHSystemIdleTimer(专用)
-(作废)支票财产;
-(作废)检查是否仍然空闲;
@结束
@RHSystemIdleTimer的实现
#pragma标记初始化/解除锁定
-(id)initSystemIdleTimerWithTimeInterval:(NSTimeInterval)ti
{
self=[super init];
如果(自我){
IOMasterPort(马赫数、马赫数和主端口);
/*获取IOHID系统*/
IOServiceGetMatchingServices(主端口、IOServiceMatching(“IOHIDSystem”)、&iter);
如果(iter==0){
NSLog(@“访问IOHIDSystem时出错\n”);
}
否则{
curObj=IOIteratorNext(iter);
如果(curObj==0){
NSLog(@“迭代器为空!\n”);
}
}
时间间隔=ti;
idleTimer=[NSTimer scheduledTimerWithTimeInterval:ti
目标:自我
选择器:@selector(checkIdleStatus)
用户信息:无
重复:否];
}
回归自我;
}
-(无效)解除锁定{
IOObjectRelease(curObj);
国际热核实验堆;
[super dealoc];
}
#pragma标记存取器
-(id)代表
{
返回代表;
}
-(无效)setDelegate:(id)接收者
{
代表=接收者;
}
#pragma标记私有方法
-(作废)支票财产
{
双空闲时间=[自系统空闲时间];
双timeLeft=时间间隔-空闲时间;
if(timeLeft=30;//基本上除以10^9(纳秒)
}
否则{
NSLog(@“找不到空闲时间\n”);
}
CFRelease((CFTypeRef)属性);
返回唐德尔;
}
@结束
不要在启动守护进程中使用CGEventSourceSecondsSinceLastEventType。
#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