4949#include < pwd.h>
5050#include < unistd.h>
5151
52+ #include < fah/screen-agent/defines.h>
53+
5254using namespace FAH ::Client;
5355using namespace cb ;
5456using namespace std ;
6668
6769
6870namespace {
71+ CFStringRef kScreenIdle = CFSTR(SCREEN_IDLE_NOTIFICATION);
72+ CFStringRef kScreenNotIdle = CFSTR(SCREEN_NOT_IDLE_NOTIFICATION);
73+
6974#pragma mark c callbacks
7075
7176 void consoleUserCB (SCDynamicStoreRef s, CFArrayRef keys, void *info) {
@@ -94,6 +99,17 @@ namespace {
9499 OSXOSImpl::instance ().requestExit ();
95100 }
96101
102+ void screenIdleCB (CFNotificationCenterRef center, void *observer,
103+ CFNotificationName name, const void *object,
104+ CFDictionaryRef info) {
105+ OSXOSImpl::instance ().noteScreenIdle ();
106+ }
107+
108+ void screenNotIdleCB (CFNotificationCenterRef center, void *observer,
109+ CFNotificationName name, const void *object,
110+ CFDictionaryRef info) {
111+ OSXOSImpl::instance ().noteScreenNotIdle ();
112+ }
97113}
98114
99115
@@ -204,7 +220,7 @@ void OSXOSImpl::run() {
204220
205221
206222void OSXOSImpl::finishInit () {
207- LOG_DEBUG (5 , " OSXOSImpl::finishInit() on thread " << pthread_self () <<
223+ LOG_DEBUG (5 , " OSXOSImpl::finishInit() on thread " << pthread_self () <<
208224 (pthread_main_np () ? " main" : " " ));
209225
210226 // Init display power state if registration succeeded
@@ -222,8 +238,10 @@ void OSXOSImpl::finishInit() {
222238
223239
224240void OSXOSImpl::updateSystemIdle () {
225- bool shouldBeIdle = displayPower == kDisplayPowerOff || loginwindowIsActive ||
226- screensaverIsActive || screenIsLocked;
241+ bool shouldBeIdle;
242+ if (gotScreenNotIdleRecently ()) shouldBeIdle = false ;
243+ else shouldBeIdle = displayPower == kDisplayPowerOff || loginwindowIsActive ||
244+ gotScreenIdleRecently ();
227245 if (shouldBeIdle == systemIsIdle) return ;
228246 systemIsIdle = shouldBeIdle;
229247 event->activate ();
@@ -483,6 +501,45 @@ bool OSXOSImpl::registerForConsoleUserNotifications() {
483501}
484502
485503
504+ void OSXOSImpl::noteScreenIdle () {
505+ screenIdleExpiry =
506+ dispatch_time (DISPATCH_TIME_NOW, SCREEN_NOTIFICATION_EXPIRES * NSEC_PER_SEC);
507+ bool wasIdle = screenIdle;
508+ screenIdle = true ;
509+ dispatch_after (screenIdleExpiry + NSEC_PER_SEC, dispatch_get_main_queue (), ^{
510+ updateSystemIdle ();
511+ });
512+ if (!wasIdle) delayedUpdateSystemIdle (5 );
513+ }
514+
515+
516+ void OSXOSImpl::noteScreenNotIdle () {
517+ screenNotIdleExpiry =
518+ dispatch_time (DISPATCH_TIME_NOW, SCREEN_NOTIFICATION_EXPIRES * NSEC_PER_SEC);
519+ screenNotIdle = true ;
520+ dispatch_after (screenNotIdleExpiry + NSEC_PER_SEC,dispatch_get_main_queue (),^{
521+ updateSystemIdle ();
522+ });
523+ updateSystemIdle ();
524+ }
525+
526+
527+ bool OSXOSImpl::gotScreenIdleRecently () {
528+ if (!screenIdle) return false ;
529+ if (dispatch_time (DISPATCH_TIME_NOW, 0 ) < screenIdleExpiry) return true ;
530+ screenIdle = false ;
531+ return false ;
532+ }
533+
534+
535+ bool OSXOSImpl::gotScreenNotIdleRecently () {
536+ if (!screenNotIdle) return false ;
537+ if (dispatch_time (DISPATCH_TIME_NOW, 0 ) < screenNotIdleExpiry) return true ;
538+ screenNotIdle = false ;
539+ return false ;
540+ }
541+
542+
486543bool OSXOSImpl::registerForDarwinNotifications () {
487544 CFNotificationCenterRef nc = CFNotificationCenterGetDarwinNotifyCenter ();
488545
@@ -496,16 +553,18 @@ bool OSXOSImpl::registerForDarwinNotifications() {
496553 CFStringRef name =
497554 CFStringCreateWithCString (0 , key.c_str (), kCFStringEncodingUTF8 );
498555
499- if (name) {
500- CFNotificationCenterAddObserver (
501- nc, (void *)this , ¬eQuitCB, name, 0 ,
502- CFNotificationSuspensionBehaviorCoalesce);
503- CFRelease (name);
556+ if (!name) return false ;
557+ CFNotificationCenterAddObserver (nc, (void *)this , ¬eQuitCB,
558+ name, 0 , CFNotificationSuspensionBehaviorCoalesce);
559+ CFRelease (name);
504560
505- return true ;
506- }
561+ CFNotificationCenterAddObserver (nc, ( void *) this , &screenIdleCB,
562+ kScreenIdle , 0 , CFNotificationSuspensionBehaviorCoalesce);
507563
508- return false ;
564+ CFNotificationCenterAddObserver (nc, (void *)this , &screenNotIdleCB,
565+ kScreenNotIdle , 0 , CFNotificationSuspensionBehaviorCoalesce);
566+
567+ return true ;
509568}
510569
511570
0 commit comments