forked from dmikushin/tray
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtray_darwin.m
96 lines (86 loc) · 3.19 KB
/
tray_darwin.m
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
#include <Cocoa/Cocoa.h>
#include "tray.h"
static int loop_status = 0;
static struct tray *tray_instance;
static NSApplication* app;
static NSStatusBar* statusBar;
static NSStatusItem* statusItem;
@interface MenuDelegate: NSObject <NSMenuDelegate>
- (void)menuWillOpen:(NSMenu *)menu;
@end
@implementation MenuDelegate{}
- (void)menuWillOpen:(NSMenu *)menu
{
if (menu == [statusItem menu] && (int)[[NSApp currentEvent] buttonNumber] == 0) {
if (tray_instance->cb != NULL) {
[menu cancelTracking];
tray_instance->cb(tray_instance);
}
}
}
- (void)menuDidClose:(NSMenu *)menu
{
id representedObject = menu.highlightedItem.representedObject;
struct tray_menu_item *pTrayMenu = [representedObject pointerValue];
if (pTrayMenu != NULL && pTrayMenu->cb != NULL) {
pTrayMenu->cb(pTrayMenu);
}
}
@end
static MenuDelegate* menuDelegate;
static NSMenu* nativeMenu(struct tray_menu_item *m) {
NSMenu* menu = [[NSMenu alloc] init];
[menu setAutoenablesItems:FALSE];
[menu setDelegate:menuDelegate];
for (; m != NULL && m->text != NULL; m++) {
if (strcmp(m->text, "-") == 0) {
[menu addItem:[NSMenuItem separatorItem]];
} else {
NSMenuItem* menuItem = [[NSMenuItem alloc]
initWithTitle:[NSString stringWithUTF8String:m->text]
action:nil
keyEquivalent:@""];
[menuItem setEnabled:m->disabled == 0 ? TRUE : FALSE];
[menuItem setState:m->checked == 1 ? TRUE : FALSE];
[menuItem setRepresentedObject:[NSValue valueWithPointer:m]];
[menu addItem:menuItem];
if (m->submenu != NULL) {
[menu setSubmenu:nativeMenu(m->submenu) forItem:menuItem];
}
}
}
return menu;
}
struct tray * tray_get_instance() {
return tray_instance;
}
int tray_init(struct tray *tray) {
menuDelegate = [[MenuDelegate alloc] init];
app = [NSApplication sharedApplication];
statusBar = [NSStatusBar systemStatusBar];
statusItem = [statusBar statusItemWithLength:NSVariableStatusItemLength];
tray_update(tray);
return 0;
}
int tray_loop(int blocking) {
NSDate* until = (blocking ? [NSDate distantFuture] : [NSDate distantPast]);
NSEvent* event = [app nextEventMatchingMask:ULONG_MAX untilDate:until
inMode:[NSString stringWithUTF8String:"kCFRunLoopDefaultMode"] dequeue:TRUE];
if (event) {
[app sendEvent:event];
}
return loop_status;
}
void tray_update(struct tray *tray) {
tray_instance = tray;
double iconHeight = [[NSStatusBar systemStatusBar] thickness];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[NSString stringWithUTF8String:tray_instance->icon_filepath]];
double width = image.size.width * (iconHeight / image.size.height);
[image setSize:NSMakeSize(width, iconHeight)];
statusItem.button.image = image;
if (tray->tooltip != NULL) {
statusItem.button.toolTip = [NSString stringWithUTF8String:tray->tooltip];
}
[statusItem setMenu:nativeMenu(tray->menu)];
}
void tray_exit(void) { loop_status = -1; }