I want to know the idle time of Mac. Currently I use this code
CFMutableDictionaryRef properties = 0;
CFTypeRef obj;
mach_port_t masterPort;
io_iterator_t iter;
io_registry_entry_t curObj;
IOMasterPort(MACH_PORT_NULL, &masterPort);
/* Get IOHIDSystem */
IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter);
if (iter == 0)
{
return -1;
}
else
{
curObj = IOIteratorNext(iter);
}
if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL)
{
obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime"));
CFRetain(obj);
}
else
{
return -1;
}
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
{
// error
tHandle = 0;
}
CFRelease(obj);
tHandle /= 1000000; // return as milliseconds
}
else
{
tHandle = -1;
}
CFRelease((CFTypeRef)properties);
IOObjectRelease(curObj);
IOObjectRelease(iter);
return (double)tHandle;
However, I want the idle time to keep 0 if any video is running.
Is there any code sample or library to check? (include video running on iTunes, VLC, youtube on browser or any other video applications)
I can interpret your question several ways:
How to determine when the screensaver kicks in?
Check the following script (original answer):
#!/bin/bash
systemSleepTimeMinutes=`pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'`
if [ $systemSleepTimeMinutes -gt "0" ]; then
systemSleepTime=`echo "$systemSleepTimeMinutes * 60" | bc`
devicesIdleTime=`ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $NF/1000000000; exit}'`
secondsBeforeSleep=`echo "$systemSleepTime - $devicesIdleTime" | bc`
echo "Time before sleep (sec): $secondsBeforeSleep"
exit 0
else
echo "The system is set to not sleep."
exit 0
fi
In case the screensaver is suppressed, for example by VLC, the result is:
The system is set to not sleep.
Otherwise it returns the time until the screensaver kicks in, for example:
Time before sleep (sec): 899.88056
Run the script above through NSTask
or NSAppleScript
and parse the result.
Please note "sleep" may also rever to the screensaver, depending on which one kicks in first.
How to determine wether the screensaver is suppressed?
The following line does the trick:
pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'
In case the screensaver is suppressed it returns 0
.
Run the line above through NSTask
or NSAppleScript
and parse the result.
How to suppress the screensaver?
The official Apple documentation (including code snippet):
How can I prevent system sleep while my application is running?
EDIT (Response to comment)
However, is there a built-in method that works the same as this script?
I'm not familiar with such a method. I actually doubt it exists.
Quick NSAppleScript
example:
NSString *source = @"do shell script \"pmset -g | grep \\\"^[ ]*sleep\\\" | awk '{ print $2 }'\"";
NSAppleScript *script= [[NSAppleScript alloc] initWithSource:source];
NSDictionary *scriptError = nil;
NSAppleEventDescriptor *descriptor=[script executeAndReturnError:&scriptError];
if(scriptError) {
NSLog(@"Error: %@",scriptError);
} else {
if ([[descriptor stringValue] intValue] == 0) {
NSLog(@"Screensaver suppressed.");
} else {
NSLog(@"Screensaver not suppressed.");
}
}
Just don't be reticent about using NSTask
or NSAppleScript
:)