diff --git a/Makefile b/Makefile index aa7cdf1..c94658e 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,8 @@ else TRAY_LDFLAGS := $(shell pkg-config --libs appindicator3-0.1) endif ifeq ($(UNAME_S),Darwin) - TRAY_CFLAGS := -DTRAY_COCOA=1 -x objective-c -framework Cocoa $< -o $@ - TRAY_LDFLAGS := + TRAY_CFLAGS := -DTRAY_APPKIT=1 -x objective-c + TRAY_LDFLAGS := -framework Cocoa endif endif diff --git a/example.c b/example.c index 8121a0b..3cddc2d 100644 --- a/example.c +++ b/example.c @@ -5,6 +5,7 @@ static struct tray tray; static void hello_cb(struct tray_menu *item) { + printf("hello cb\n"); if (strcmp(tray.icon, "indicator-messages") == 0) { tray.icon = "indicator-messages-new"; } else { @@ -14,6 +15,7 @@ static void hello_cb(struct tray_menu *item) { } static void quit_cb(struct tray_menu *item) { + printf("quit cb\n"); tray_exit(); } @@ -28,6 +30,8 @@ static struct tray tray = { int main(int argc, char *argv[]) { tray_init(&tray); - while (tray_loop(1) == 0); + while (tray_loop(1) == 0) { + printf("iteration\n"); + } return 0; } diff --git a/tray.h b/tray.h index 24207e2..01ccbe9 100644 --- a/tray.h +++ b/tray.h @@ -56,10 +56,7 @@ static void tray_update(struct tray *tray) { app_indicator_set_icon(indicator, tray->icon); GtkMenuShell *gtk_menu = (GtkMenuShell *)gtk_menu_new(); - for (m = tray->menu;; m++) { - if (m->text == NULL) { - break; - } + for (struct tray_menu *m = tray->menu; m != NULL && m->text != NULL; m++) { GtkWidget *item = gtk_menu_item_new_with_label(m->text); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(gtk_menu), item); @@ -75,6 +72,84 @@ static void tray_exit() { } #elif defined(TRAY_APPKIT) + +#import + +static NSAutoreleasePool *pool; +static NSStatusBar *statusBar; +static id statusItem; +static id statusBarButton; + +@interface Tray : NSObject +- (void) menuCallback: (id) sender; +@end +@implementation Tray +- (void) menuCallback: (id) sender { + struct tray_menu *m = (struct tray_menu *) + [[sender representedObject] pointerValue]; + m->cb(m); +} +@end + +static int tray_init(struct tray *tray) { + pool = [NSAutoreleasePool new]; + [NSApplication sharedApplication]; + + Tray *trayDelegate = [Tray new]; + [NSApp setDelegate: trayDelegate]; + + statusBar = [NSStatusBar systemStatusBar]; + statusItem = [statusBar statusItemWithLength:NSVariableStatusItemLength]; + [statusItem retain]; + [statusItem setHighlightMode:YES]; + statusBarButton = [statusItem button]; + + tray_update(tray); + [NSApp activateIgnoringOtherApps:YES]; + return -1; +} + +static int tray_loop(int blocking) { + NSEvent *event; + NSDate *until = (blocking ? [NSDate distantFuture] : [NSDate distantPast]); + event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:until + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event) { + [NSApp sendEvent:event]; + } + return 0; +} + +static void tray_update(struct tray *tray) { + [statusBarButton setImage:[NSImage imageNamed:@"icon.png"]]; + + NSMenu *menu = [NSMenu new]; + [menu autorelease]; + [menu setAutoenablesItems:NO]; + for (struct tray_menu *m = tray->menu; m != NULL && m->text != NULL; m++) { + NSMenuItem *menuItem = [NSMenuItem alloc]; + [menuItem autorelease]; + [menuItem + initWithTitle: [NSString stringWithUTF8String: m->text] + action:@selector(menuCallback:) + keyEquivalent:@""]; + [menuItem setEnabled:YES]; + [menuItem setRepresentedObject: [NSValue valueWithPointer:m]]; + + [menu addItem:menuItem]; + + //[menu addItem:[NSMenuItem separatorItem]]; + } + + [statusItem setMenu:menu]; +} + +static void tray_exit() { + [NSApp terminate:NSApp]; +} + #elif defined(TRAY_WINAPI) #else #endif