forked from h4llow3En/mac-notification-sys
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnotify.h
More file actions
121 lines (102 loc) · 4.84 KB
/
notify.h
File metadata and controls
121 lines (102 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#import <Cocoa/Cocoa.h>
#import <CoreServices/CoreServices.h>
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
NSString* fakeBundleIdentifier = nil;
NSString* getBundleIdentifier(NSString* appName);
BOOL setApplication(NSString* newbundleIdentifier);
NSDictionary* sendNotification(NSString* title, NSString* subtitle, NSString* message, NSDictionary* options);
@implementation NSBundle (swizzle)
- (NSString*)__bundleIdentifier {
if (self == [NSBundle mainBundle]) {
return fakeBundleIdentifier ? fakeBundleIdentifier : @"com.apple.Terminal";
} else {
return [self __bundleIdentifier];
}
}
@end
BOOL installNSBundleHook(void) {
Class class = objc_getClass("NSBundle");
if (class) {
method_exchangeImplementations(class_getInstanceMethod(class, @selector(bundleIdentifier)),
class_getInstanceMethod(class, @selector(__bundleIdentifier)));
return YES;
}
return NO;
}
@interface NotificationCenterDelegate: NSObject <NSUserNotificationCenterDelegate>
@property(nonatomic, assign) BOOL keepRunning;
@property(nonatomic, assign) BOOL waitForClick;
@property(nonatomic, retain) NSDictionary* actionData;
@end
// Delegate to respond to events in the NSUserNotificationCenter
// See https://developer.apple.com/documentation/foundation/nsusernotificationcenterdelegate?language=objc
@implementation NotificationCenterDelegate
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
didDeliverNotification:(NSUserNotification*)notification {
// Stop running if we're not expecting a response
if (!notification.hasActionButton && !notification.hasReplyButton && !self.waitForClick) {
self.keepRunning = NO;
}
}
// Most typical actions
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
didActivateNotification:(NSUserNotification*)notification {
long long additionalActionIndex = ULONG_MAX;
// Switch on how the notification was interacted with
// See https://developer.apple.com/documentation/foundation/nsusernotification/1416143-activationtype?language=objc
switch (notification.activationType) {
case NSUserNotificationActivationTypeActionButtonClicked:
case NSUserNotificationActivationTypeAdditionalActionClicked: {
if ([[(NSObject*)notification valueForKey:@"_alternateActionButtonTitles"] count] > 1) {
NSNumber* alternateActionIndex = [(NSObject*)notification valueForKey:@"_alternateActionIndex"];
additionalActionIndex = [alternateActionIndex unsignedLongLongValue];
if (additionalActionIndex == LONG_MAX) {
self.actionData = @{@"activationType": @"actionClicked", @"activationValue": notification.actionButtonTitle};
break;
}
NSString* ActionsClicked = [(NSObject*)notification valueForKey:@"_alternateActionButtonTitles"][additionalActionIndex];
self.actionData = @{@"activationType": @"actionClicked", @"activationValue": ActionsClicked, @"activationValueIndex": [NSString stringWithFormat:@"%llu", additionalActionIndex]};
} else {
self.actionData = @{@"activationType": @"actionClicked", @"activationValue": notification.actionButtonTitle};
}
break;
}
case NSUserNotificationActivationTypeContentsClicked: {
self.actionData = @{@"activationType": @"contentsClicked"};
break;
}
case NSUserNotificationActivationTypeReplied: {
self.actionData = @{@"activationType": @"replied", @"activationValue": notification.response.string};
break;
}
case NSUserNotificationActivationTypeNone:
default: {
self.actionData = @{@"activationType": @"none"};
break;
}
}
// Stop running after interacting with the notification
self.keepRunning = NO;
// Force-close the notification after interacting with it
[center removeDeliveredNotification:notification];
}
// Specific to the close/other button
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
didDismissAlert:(NSUserNotification*)notification {
self.actionData = @{@"activationType": @"closeClicked", @"activationValue": notification.otherButtonTitle};
// Stop running after interacting with the notification
self.keepRunning = NO;
// Force-close the notification after interacting with it
[center removeDeliveredNotification:notification];
}
@end
// Utility function to create an NSImage from an url
NSImage* getImageFromURL(NSString* url) {
NSURL* imageURL = [NSURL URLWithString:url];
if ([[imageURL scheme] length] == 0) {
// Prefix 'file://' if no scheme
imageURL = [NSURL fileURLWithPath:url];
}
return [[NSImage alloc] initWithContentsOfURL:imageURL];
}