diff --git a/internal/gui/lightweight.go b/internal/gui/lightweight.go index d318a6eb..1fe2683f 100644 --- a/internal/gui/lightweight.go +++ b/internal/gui/lightweight.go @@ -108,6 +108,10 @@ func (h *host) makePanel() *application.WebviewWindow { if h.tray != nil { h.tray.AttachWindow(w).WindowOffset(6) } + // the icon stays lit while the panel is open (the Mac's) + trayOwnClicks() + w.OnWindowEvent(events.Mac.WindowShow, func(*application.WindowEvent) { trayHighlight(true) }) + w.OnWindowEvent(events.Mac.WindowHide, func(*application.WindowEvent) { trayHighlight(false) }) return w } diff --git a/internal/gui/trayimage_darwin.go b/internal/gui/trayimage_darwin.go index 9bbb1e49..61a4c69f 100644 --- a/internal/gui/trayimage_darwin.go +++ b/internal/gui/trayimage_darwin.go @@ -320,6 +320,31 @@ static void mpHide(void) { }); } +// mpHighlight lights the item while its panel is open, as the system's own +// items do. +static void mpHighlight(int on) { + dispatch_async(dispatch_get_main_queue(), ^{ + [mpButton() highlight:on != 0]; + }); +} + +// mpOwnClicks hands a left click on the item to its action before the +// button sees it: the button's own tracking would light it on mouse-down +// and put it out on mouse-up, a flicker before mpHighlight's. +static void mpOwnClicks(void) { + static dispatch_once_t once; + dispatch_once(&once, ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown handler:^NSEvent *(NSEvent *e) { + NSStatusBarButton *b = mpButton(); + if (b == nil || e.window != b.window) return e; + [NSApp sendAction:b.action to:b.target from:b]; + return nil; + }]; + }); + }); +} + // mpPNG draws the image as the menu bar would at scale, light or dark, on // the bar's colour when bg is set: for tests and previews. static void *mpPNG(mpTrayCell *cells, int n, const void *bird, int len, CGFloat h, CGFloat scale, int dark, int bg, int *outLen, int *pxW, int *pxH) { @@ -431,6 +456,12 @@ func trayImageFrame(bird []byte) bool { // trayImageHide takes the cells down; the icon set next is the bird alone. func trayImageHide() { C.mpHide() } +// trayHighlight lights the tray icon, or puts it out. +func trayHighlight(on bool) { C.mpHighlight(cBool(on)) } + +// trayOwnClicks keeps the button's own highlight out of a click (mpOwnClicks). +func trayOwnClicks() { C.mpOwnClicks() } + // trayImagePNG is the image as the menu bar h points high draws it at // scale (2 for a Retina screen), light or dark, on the bar's colour when // bg; with its size in pixels. diff --git a/internal/gui/trayimage_other.go b/internal/gui/trayimage_other.go index 4f23a070..41c4bf2f 100644 --- a/internal/gui/trayimage_other.go +++ b/internal/gui/trayimage_other.go @@ -10,3 +10,7 @@ func trayImageShow([]trayCell, []byte) bool { return false } func trayImageFrame([]byte) bool { return false } func trayImageHide() {} + +func trayHighlight(bool) {} + +func trayOwnClicks() {}