aboutsummaryrefslogtreecommitdiffstats
path: root/notifier_darwin.m
diff options
context:
space:
mode:
Diffstat (limited to 'notifier_darwin.m')
-rw-r--r--notifier_darwin.m88
1 files changed, 80 insertions, 8 deletions
diff --git a/notifier_darwin.m b/notifier_darwin.m
index 6e46b15..6e4c5ac 100644
--- a/notifier_darwin.m
+++ b/notifier_darwin.m
@@ -2,6 +2,7 @@
// this source code is governed by the included BSD license.
// Modified from https://github.com/julienXX/terminal-notifier
+// Modified from https://github.com/vjeantet/alerter
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
@@ -27,10 +28,12 @@ static BOOL installFakeBundleIdentifierHook() {
}
@interface NotificationDelegate : NSObject <NSUserNotificationCenterDelegate>
+@property NSTimeInterval timeout;
+@property (retain) NSString *uuid;
@end
CFStringRef deliverNotification(CFStringRef titleRef, CFStringRef subtitleRef, CFStringRef messageRef, CFStringRef appIconURLStringRef,
- CFArrayRef actionsRef, CFStringRef bundleIDRef, CFStringRef groupIDRef) {
+ CFArrayRef actionsRef, CFStringRef bundleIDRef, CFStringRef groupIDRef, NSTimeInterval timeout) {
if (bundleIDRef) {
_fakeBundleIdentifier = (NSString *)bundleIDRef;
@@ -58,26 +61,95 @@ CFStringRef deliverNotification(CFStringRef titleRef, CFStringRef subtitleRef, C
}
NSArray *actions = (NSArray *)actionsRef;
if ([actions count] >= 1) {
- userNotification.actionButtonTitle = [actions objectAtIndex:0];
[userNotification setValue:@YES forKey:@"_showsButtons"];
- }
- if ([actions count] >= 2) {
- userNotification.otherButtonTitle = [actions objectAtIndex:1];
+ if ([actions count] >= 2) {
+ [userNotification setValue:@YES forKey:@"_alwaysShowAlternateActionMenu"];
+ [userNotification setValue:actions forKey:@"_alternateActionButtonTitles"];
+ } else {
+ userNotification.actionButtonTitle = [actions objectAtIndex:0];
+ }
}
NSUserNotificationCenter *userNotificationCenter = [NSUserNotificationCenter defaultUserNotificationCenter];
//NSLog(@"Deliver: %@", userNotification);
- userNotificationCenter.delegate = [[NotificationDelegate alloc] init];
- [userNotificationCenter scheduleNotification:userNotification];
+ NotificationDelegate *delegate = [[NotificationDelegate alloc] init];
+ delegate.timeout = timeout;
+ delegate.uuid = uuid;
+ userNotificationCenter.delegate = delegate;
+ [userNotificationCenter deliverNotification:userNotification];
+
[[NSRunLoop mainRunLoop] run];
+
return nil;
}
@implementation NotificationDelegate
+
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)userNotification {
return YES;
}
+
+- (void)remove:(NSUserNotification *)userNotification center:(NSUserNotificationCenter *)center {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [center removeDeliveredNotification:userNotification];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ fflush(stdout);
+ fflush(stderr);
+ exit(0);
+ });
+ });
+}
+
+- (NSString *)JSON:(NSDictionary *)dict {
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
+ if (!jsonData) return @"";
+ return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
+}
+
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)userNotification {
- exit(0);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSDate *start = [NSDate date];
+ while (-[start timeIntervalSinceNow] < self.timeout) {
+ bool found = NO;
+ for (NSUserNotification *deliveredNotification in [[NSUserNotificationCenter defaultUserNotificationCenter] deliveredNotifications]) {
+ if ([deliveredNotification.userInfo[@"uuid"] isEqual:self.uuid]) {
+ [NSThread sleepForTimeInterval:0.5];
+ found = YES;
+ break;
+ }
+ }
+ if (!found) break;
+ }
+ [self remove:userNotification center:center];
+ });
+}
+
+- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)userNotification {
+ switch (userNotification.activationType) {
+ case NSUserNotificationActivationTypeAdditionalActionClicked:
+ case NSUserNotificationActivationTypeActionButtonClicked: {
+ NSString *action = nil;
+ if ([[(NSObject*)userNotification valueForKey:@"_alternateActionButtonTitles"] count] > 1) {
+ NSNumber *alternateActionIndex = [(NSObject*)userNotification valueForKey:@"_alternateActionIndex"];
+ int actionIndex = [alternateActionIndex intValue];
+ action = [(NSObject*)userNotification valueForKey:@"_alternateActionButtonTitles"][actionIndex];
+ } else {
+ action = userNotification.actionButtonTitle;
+ }
+ NSLog(@"%@", [self JSON:@{@"action": action}]);
+ break;
+ }
+ case NSUserNotificationActivationTypeContentsClicked:
+ //NSLog(@"contents");
+ break;
+ case NSUserNotificationActivationTypeReplied:
+ //NSLog(@"replied");
+ break;
+ case NSUserNotificationActivationTypeNone:
+ //NSLog(@"none");
+ break;
+ }
+ [self remove:userNotification center:center];
}
+
@end