Created
May 21, 2020 18:49
-
-
Save thenextman/41ff0068c74d33d366c4df56d3b079f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <Cocoa/Cocoa.h> | |
#import <AppKit/AppKit.h> | |
#import <SystemConfiguration/SystemConfiguration.h> | |
#import <Carbon/Carbon.h> | |
#import <CoreFoundation/CoreFoundation.h> | |
static CFStringRef CopyCurrentConsoleUsername(SCDynamicStoreRef store) | |
{ | |
CFStringRef result; | |
result = SCDynamicStoreCopyConsoleUser(store, NULL, NULL); | |
if ((result) && CFEqual(result, CFSTR("loginwindow"))) | |
{ | |
CFRelease(result); | |
result = NULL; | |
} | |
return result; | |
} | |
static CFStringRef gCurrentConsoleUser; | |
static void onSCConsoleUserChange(SCDynamicStoreRef store, CFArrayRef changedKeys, void* info) | |
{ | |
CFStringRef currentConsoleUser; | |
Boolean didChange; | |
currentConsoleUser = CopyCurrentConsoleUsername(store); | |
didChange = (gCurrentConsoleUser != NULL) != (currentConsoleUser != NULL); | |
if (!didChange && (gCurrentConsoleUser != NULL) ) | |
{ | |
didChange = !CFEqual(gCurrentConsoleUser, currentConsoleUser); | |
} | |
if (didChange) | |
{ | |
if (gCurrentConsoleUser) | |
CFRelease(gCurrentConsoleUser); | |
gCurrentConsoleUser = currentConsoleUser; | |
if (gCurrentConsoleUser) | |
CFRetain(gCurrentConsoleUser); | |
NSLog(@"gCurrentConsoleUser: %@", (__bridge NSString*) gCurrentConsoleUser); | |
} | |
} | |
OSStatus onCarbonNotification(EventHandlerCallRef nextHandler, EventRef switchEvent, void* userData) | |
{ | |
if (GetEventKind(switchEvent)== kEventSystemUserSessionActivated) | |
{ | |
NSLog(@"kEventSystemUserSessionActivated"); | |
} | |
else if (GetEventKind(switchEvent)== kEventSystemUserSessionDeactivated) | |
{ | |
NSLog(@"kEventSystemUserSessionDeactivated"); | |
} | |
return noErr; | |
} | |
void onDistNotification(CFNotificationCenterRef center, void* observer, CFNotificationName name, const void* object, CFDictionaryRef userInfo) | |
{ | |
NSLog(@"onDistNotification: %@", (__bridge NSString*) name); | |
} | |
@interface Notifier : NSObject | |
{ | |
} | |
@end | |
@implementation Notifier | |
- (void)onWorkspaceNotification:(NSNotification*)notification | |
{ | |
if ([notification.name isEqualToString:NSWorkspaceSessionDidBecomeActiveNotification]) | |
{ | |
NSLog(@"NSWorkspaceSessionDidBecomeActiveNotification"); | |
} | |
else if ([notification.name isEqualToString:NSWorkspaceSessionDidBecomeActiveNotification]) | |
{ | |
NSLog(@"NSWorkspaceSessionDidResignActiveNotification"); | |
} | |
} | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (self) | |
{ | |
// | |
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self | |
selector:@selector(onWorkspaceNotification:) | |
name:NSWorkspaceSessionDidBecomeActiveNotification | |
object:nil]; | |
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self | |
selector:@selector(onWorkspaceNotification:) | |
name:NSWorkspaceSessionDidResignActiveNotification | |
object:nil]; | |
// | |
EventTypeSpec switchEventTypes[2]; | |
EventHandlerUPP switchEventHandler; | |
switchEventTypes[0].eventClass = kEventClassSystem; | |
switchEventTypes[0].eventKind = kEventSystemUserSessionDeactivated; | |
switchEventTypes[1].eventClass = kEventClassSystem; | |
switchEventTypes[1].eventKind = kEventSystemUserSessionActivated; | |
switchEventHandler = NewEventHandlerUPP(onCarbonNotification); | |
InstallApplicationEventHandler(switchEventHandler, 2, switchEventTypes, NULL, NULL); | |
// | |
Boolean success; | |
SCDynamicStoreRef store; | |
CFStringRef key; | |
CFArrayRef keys; | |
CFRunLoopSourceRef rls; | |
store = SCDynamicStoreCreate(NULL, CFSTR("com.apple.dts.ConsoleUser"), onSCConsoleUserChange, NULL); | |
key = SCDynamicStoreKeyCreateConsoleUser(NULL); | |
keys = CFArrayCreate(NULL, (const void **) &key, 1, &kCFTypeArrayCallBacks); | |
success = SCDynamicStoreSetNotificationKeys(store, keys, NULL); | |
rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); | |
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); | |
gCurrentConsoleUser = CopyCurrentConsoleUsername(store); | |
NSLog(@"gCurrentConsoleUser: %@", (__bridge NSString*) gCurrentConsoleUser); | |
// | |
CFNotificationCenterRef distNc = CFNotificationCenterGetDistributedCenter(); | |
CFNotificationCenterAddObserver(distNc, (__bridge const void *) self, onDistNotification, (__bridge CFStringRef) @"com.apple.screensaver.didlaunch", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, (__bridge const void *) self, onDistNotification, (__bridge CFStringRef) @"com.apple.screensaver.didstart", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, NULL, onDistNotification, (__bridge CFStringRef) @"com.apple.screensaver.didstop", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, NULL, onDistNotification, (__bridge CFStringRef) @"com.apple.shieldWindowRaised", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, NULL, onDistNotification, (__bridge CFStringRef) @"com.apple.shieldWindowLowered", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, NULL, onDistNotification, (__bridge CFStringRef) @"com.apple.screenIsLocked", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, NULL, onDistNotification, (__bridge CFStringRef) @"com.apple.screenIsUnlocked", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, (__bridge const void *) self, onDistNotification, (__bridge CFStringRef) @"com.apple.sessionDidMoveOffConsole", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
CFNotificationCenterAddObserver(distNc, (__bridge const void *) self, onDistNotification, (__bridge CFStringRef) @"com.apple.sessionDidMoveOnConsole", nil, | |
CFNotificationSuspensionBehaviorDeliverImmediately); | |
// com.apple.userWillLogOut | |
} | |
return self; | |
} | |
@end | |
int main(int argc, const char * argv[]) | |
{ | |
@autoreleasepool | |
{ | |
Notifier* notifier = [[Notifier alloc] init]; | |
CFRunLoopRun(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment