diff --git a/ProcWatcher.h b/ProcWatcher.h new file mode 100644 index 0000000..f834fdd --- /dev/null +++ b/ProcWatcher.h @@ -0,0 +1,8 @@ +#import + +@interface ProcWatcher : NSObject ++ (instancetype) shared; +- (void) startWatching; +@end + + diff --git a/ProcWatcher.m b/ProcWatcher.m new file mode 100644 index 0000000..f152ee3 --- /dev/null +++ b/ProcWatcher.m @@ -0,0 +1,49 @@ +#include "_cgo_export.h" +#import "ProcWatcher.h" + +@implementation ProcWatcher + ++ (instancetype) shared { + static id sharedInstance; + static dispatch_once_t predicate; + + dispatch_once(&predicate, ^{ + sharedInstance = [ProcWatcher new]; + }); + return sharedInstance; +} + +- (void) startWatching { + NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; + NSNotificationCenter* notifications = [workspace notificationCenter]; + + void (^handleAppLaunch) (NSNotification*) = ^(NSNotification* note) { + NSDictionary* info = note.userInfo; + NSRunningApplication* app = info[NSWorkspaceApplicationKey]; + NSString* bundleId = app.bundleIdentifier; + + AppStarted((GoString){bundleId.UTF8String, bundleId.length}); + }; + + id observerLaunch = [notifications + addObserverForName: NSWorkspaceDidLaunchApplicationNotification + object: workspace + queue: [NSOperationQueue mainQueue] + usingBlock: handleAppLaunch]; + + void (^handleAppTerminate) (NSNotification*) = ^(NSNotification* note) { + NSDictionary* info = note.userInfo; + NSRunningApplication* app = info[NSWorkspaceApplicationKey]; + NSString* bundleId = app.bundleIdentifier; + + AppEnded((GoString){bundleId.UTF8String, bundleId.length}); + }; + + id observerTerminate = [notifications + addObserverForName: NSWorkspaceDidTerminateApplicationNotification + object: workspace + queue: [NSOperationQueue mainQueue] + usingBlock: handleAppTerminate]; +} + +@end diff --git a/procmon.c b/procmon.c new file mode 100644 index 0000000..96734ca --- /dev/null +++ b/procmon.c @@ -0,0 +1,8 @@ +#include "procmon.h" +#include +#include "ProcWatcher.h" + +void MonitorProcesses() { + [[ProcWatcher shared] startWatching]; + [[NSRunLoop currentRunLoop] run]; +} diff --git a/procmon.go b/procmon.go index f863e26..c25ba9c 100644 --- a/procmon.go +++ b/procmon.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "runtime" ) /* @@ -12,12 +11,42 @@ import ( */ import "C" -//export TheGoFunc -func TheGoFunc(name string) { - fmt.Printf("hi from c: %s\n", name) +var appChanges = make(chan appStateChange, 1) + +type stateChange uint + +const ( + stateStarted stateChange = iota + stateEnded +) + +type appStateChange struct { + stateChange + appname string +} + +//export AppStarted +func AppStarted(name string) { + appChanges <- appStateChange{stateStarted, name} +} + +//export AppEnded +func AppEnded(name string) { + appChanges <- appStateChange{stateEnded, name} +} + +func reportChanges() { + for change := range appChanges { + switch change.stateChange { + case stateStarted: + fmt.Printf("started: %s\n", change.appname) + case stateEnded: + fmt.Printf("terminated: %s\n", change.appname) + } + } } func main() { - C.TheCFunc() - runtime.Goexit() + go reportChanges() + C.MonitorProcesses() } diff --git a/procmon.h b/procmon.h index b91a0e2..1e7e220 100644 --- a/procmon.h +++ b/procmon.h @@ -1,3 +1 @@ -#import - -void TheCFunc(); +void MonitorProcesses(); diff --git a/procmon.m b/procmon.m deleted file mode 100644 index 3abaee6..0000000 --- a/procmon.m +++ /dev/null @@ -1,66 +0,0 @@ -#include "procmon.h" -#import "_cgo_export.h" -#import - -@interface ProcWatcher : NSObject -+ (instancetype) shared; -- (void) applicationDidLaunch:(NSNotification*) notification; -@end - -@implementation ProcWatcher - -+ (instancetype) shared { - static id sharedInstance; - static dispatch_once_t predicate; - - NSLog(@"ProcWatcher shared instance accessed"); - - dispatch_once(&predicate, ^{ - TheGoFunc((GoString){"dispatch", 8}); - sharedInstance = [ProcWatcher new]; - }); - return sharedInstance; -} - -- (void) applicationDidLaunch:(NSNotification*) notification { - NSDictionary* info = notification.userInfo; - NSRunningApplication* app = info[NSWorkspaceApplicationKey]; - NSString* bundleId = app.bundleIdentifier; - - NSLog(@"application launched: %@", bundleId); - - TheGoFunc((GoString){bundleId.UTF8String, bundleId.length}); -} - -@end - -void TheCFunc() { - NSLog(@"current run loop: %@", [NSRunLoop currentRunLoop]); - NSLog(@"current run loop mode: %@", [[NSRunLoop currentRunLoop] currentMode]); - NSLog(@"current run loop mode: %@", [[NSRunLoop currentRunLoop] currentMode]); - - if ([NSThread isMainThread]) { - NSLog(@"TheCFunc is in the main thread"); - } else { - NSLog(@"TheCFunc is NOT in the main thread"); - } - - NSLog(@"hi from nslog"); - TheGoFunc((GoString){"hi", 2}); - - NSArray* running = [[NSWorkspace sharedWorkspace] runningApplications]; - NSLog(@"%@", running); - - ProcWatcher* pw = [ProcWatcher shared]; - - NSNotificationCenter* notifications = [[NSWorkspace sharedWorkspace] notificationCenter]; - - [notifications - addObserver: pw - selector: @selector(applicationDidLaunch:) - name: NSWorkspaceDidLaunchApplicationNotification object: nil]; - - NSLog(@"thing has finished"); - - [[NSRunLoop currentRunLoop] run]; -}