diff --git a/v2/internal/ffenestri/ffenestri.h b/v2/internal/ffenestri/ffenestri.h index 7aa1b76cb..a93b37642 100644 --- a/v2/internal/ffenestri/ffenestri.h +++ b/v2/internal/ffenestri/ffenestri.h @@ -36,5 +36,6 @@ extern void UpdateMenu(void *app, char *menuAsJSON); extern void UpdateTray(void *app, char *menuAsJSON); extern void UpdateContextMenus(void *app, char *contextMenusAsJSON); extern void UpdateTrayLabel(void *app, const char *label); +extern void UpdateTrayIcon(void *app, const char *label); #endif diff --git a/v2/internal/ffenestri/ffenestri_client.go b/v2/internal/ffenestri/ffenestri_client.go index d1be11151..0e14b68ab 100644 --- a/v2/internal/ffenestri/ffenestri_client.go +++ b/v2/internal/ffenestri/ffenestri_client.go @@ -188,10 +188,15 @@ func (c *Client) UpdateTray(menu *menu.Menu) { } C.UpdateTray(c.app.app, c.app.string2CString(string(trayMenuJSON))) } + func (c *Client) UpdateTrayLabel(label string) { C.UpdateTrayLabel(c.app.app, c.app.string2CString(label)) } +func (c *Client) UpdateTrayIcon(name string) { + C.UpdateTrayIcon(c.app.app, c.app.string2CString(name)) +} + func (c *Client) UpdateContextMenus(contextMenus *menu.ContextMenus) { // Guard against nil contextMenus diff --git a/v2/internal/ffenestri/ffenestri_darwin.c b/v2/internal/ffenestri/ffenestri_darwin.c index afff648ab..38740edf2 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.c +++ b/v2/internal/ffenestri/ffenestri_darwin.c @@ -78,6 +78,14 @@ #define NSEventTypeRightMouseDown 3 #define NSEventTypeRightMouseUp 4 +#define NSNoImage 0 +#define NSImageOnly 1 +#define NSImageLeft 2 +#define NSImageRight 3 +#define NSImageBelow 4 +#define NSImageAbove 5 +#define NSImageOverlaps 6 + // References to assets extern const unsigned char *assets[]; @@ -219,9 +227,9 @@ struct Application { // Tray const char *trayMenuAsJSON; - const char *trayType; const char *trayLabel; const char *trayIconName; + int trayIconPosition; JsonNode *processedTrayMenu; id statusItem; @@ -823,9 +831,9 @@ void* NewApplication(const char *title, int width, int height, int resizable, in // Tray result->trayMenuAsJSON = NULL; - result->trayType = NULL; result->trayLabel = NULL; result->trayIconName = NULL; + result->trayIconPosition = NSImageLeft; // Left of the text by default result->processedTrayMenu = NULL; result->statusItem = NULL; @@ -1344,9 +1352,8 @@ void SetMenu(struct Application *app, const char *menuAsJSON) { } // SetTray sets the initial tray menu for the application -void SetTray(struct Application *app, const char *trayMenuAsJSON, const char *trayType, const char *trayLabel, const char *trayIconName) { +void SetTray(struct Application *app, const char *trayMenuAsJSON, const char *trayLabel, const char *trayIconName) { app->trayMenuAsJSON = trayMenuAsJSON; - app->trayType = trayType; app->trayLabel = trayLabel; app->trayIconName = trayIconName; } @@ -2267,6 +2274,13 @@ void UpdateTrayLabel(struct Application *app, const char *label) { msg(statusBarButton, s("setTitle:"), str(label)); } +void UpdateTrayIcon(struct Application *app, const char *name) { + id trayImage = hashmap_get(&trayIconCache, name, strlen(name)); + id statusBarButton = msg(app->statusItem, s("button")); + msg(statusBarButton, s("setImagePosition:"), 2); + msg(statusBarButton, s("setImage:"), trayImage); +} + void processTrayIconData(struct Application *app) { unsigned int count = 0; @@ -2312,18 +2326,16 @@ void parseTrayData(struct Application *app) { statusItem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength); app->statusItem = statusItem; msg(statusItem, s("retain")); - id statusBarButton = msg(statusItem, s("button")); + id statusBarButton = msg(app->statusItem, s("button")); + msg(statusBarButton, s("setImagePosition:"), app->trayIconPosition); - if( STREQ(app->trayType, "icon") ) { - // Get the icon - if ( app->trayIconName != NULL ) { - id trayImage = hashmap_get(&trayIconCache, app->trayIconName, strlen(app->trayIconName)); - msg(statusBarButton, s("setImage:"), trayImage); - } + // Get the icon + if ( app->trayIconName != NULL ) { + UpdateTrayIcon(app, app->trayIconName); } - if( STREQ(app->trayType, "label") ) { - // If we have a tray icon - msg(statusBarButton, s("setTitle:"), str(app->trayLabel)); + + if( app->trayLabel != NULL ) { + UpdateTrayLabel(app, app->trayLabel); } } @@ -2365,12 +2377,6 @@ void parseTrayData(struct Application *app) { processRadioGroup(radioGroup, &menuItemMapForTrayMenu, &radioGroupMapForTrayMenu); } - -// msg(statusBarButton, s("setImage:"), -// msg(c("NSImage"), s("imageNamed:"), -// msg(c("NSString"), s("stringWithUTF8String:"), tray->icon))); - - msg(statusItem, s("setMenu:"), traymenu); } diff --git a/v2/internal/ffenestri/ffenestri_darwin.go b/v2/internal/ffenestri/ffenestri_darwin.go index afa162b67..536f03663 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.go +++ b/v2/internal/ffenestri/ffenestri_darwin.go @@ -99,7 +99,7 @@ func (a *Application) processPlatformSettings() error { if err != nil { return err } - C.SetTray(a.app, a.string2CString(string(trayMenuJSON)), a.string2CString(string(tray.Type)), a.string2CString(tray.Label), a.string2CString(tray.Icon)) + C.SetTray(a.app, a.string2CString(string(trayMenuJSON)), a.string2CString(tray.Label), a.string2CString(tray.Icon)) } // Process context menus diff --git a/v2/internal/ffenestri/ffenestri_darwin.h b/v2/internal/ffenestri/ffenestri_darwin.h index 76260164d..3ca846044 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.h +++ b/v2/internal/ffenestri/ffenestri_darwin.h @@ -13,7 +13,7 @@ extern void SetAppearance(void *, const char *); extern void WebviewIsTransparent(void *); extern void WindowBackgroundIsTranslucent(void *); extern void SetMenu(void *, const char *); -extern void SetTray(void *, const char *, const char *, const char *, const char *); +extern void SetTray(void *, const char *, const char *, const char *); extern void SetContextMenus(void *, const char *); #endif \ No newline at end of file diff --git a/v2/internal/messagedispatcher/dispatchclient.go b/v2/internal/messagedispatcher/dispatchclient.go index cf822fce3..6ef7389b1 100644 --- a/v2/internal/messagedispatcher/dispatchclient.go +++ b/v2/internal/messagedispatcher/dispatchclient.go @@ -34,6 +34,7 @@ type Client interface { UpdateMenu(menu *menu.Menu) UpdateTray(menu *menu.Menu) UpdateTrayLabel(label string) + UpdateTrayIcon(name string) UpdateContextMenus(contextMenus *menu.ContextMenus) } diff --git a/v2/internal/messagedispatcher/messagedispatcher.go b/v2/internal/messagedispatcher/messagedispatcher.go index fb19a7c80..bf9a10922 100644 --- a/v2/internal/messagedispatcher/messagedispatcher.go +++ b/v2/internal/messagedispatcher/messagedispatcher.go @@ -523,6 +523,21 @@ func (d *Dispatcher) processTrayMessage(result *servicebus.Message) { client.frontend.UpdateTrayLabel(updatedLabel) } + case "seticon": + + iconname, ok := result.Data().(string) + if !ok { + d.logger.Error("Invalid data for 'trayfrontend:seticon' : %#v", + result.Data()) + return + } + + // TODO: Work out what we mean in a multi window environment... + // For now we will just pick the first one + for _, client := range d.clients { + client.frontend.UpdateTrayIcon(iconname) + } + default: d.logger.Error("Unknown menufrontend command: %s", command) } diff --git a/v2/internal/runtime/tray.go b/v2/internal/runtime/tray.go index e8420ed79..07d96f979 100644 --- a/v2/internal/runtime/tray.go +++ b/v2/internal/runtime/tray.go @@ -13,6 +13,7 @@ type Tray interface { GetByID(menuID string) *menu.MenuItem RemoveByID(id string) bool SetLabel(label string) + SetIcon(name string) } type trayRuntime struct { @@ -43,6 +44,9 @@ func (t *trayRuntime) Update() { func (t *trayRuntime) SetLabel(label string) { t.bus.Publish("tray:setlabel", label) } +func (t *trayRuntime) SetIcon(name string) { + t.bus.Publish("tray:seticon", name) +} func (t *trayRuntime) GetByID(menuID string) *menu.MenuItem { return t.trayMenu.Menu.GetByID(menuID) diff --git a/v2/internal/subsystem/tray.go b/v2/internal/subsystem/tray.go index 45c9b9681..1da5fde58 100644 --- a/v2/internal/subsystem/tray.go +++ b/v2/internal/subsystem/tray.go @@ -126,6 +126,14 @@ func (t *Tray) Start() error { // Notify frontend of menu change t.bus.Publish("trayfrontend:setlabel", updatedLabel) + // Make sure we catch any icon updates + case "seticon": + iconname := menuMessage.Data().(string) + t.trayMenu.Label = iconname + + // Notify frontend of menu change + t.bus.Publish("trayfrontend:seticon", iconname) + default: t.logger.Error("unknown tray message: %+v", menuMessage) } diff --git a/v2/pkg/menu/trayoptions.go b/v2/pkg/menu/trayoptions.go index a45c9d39d..b058097d8 100644 --- a/v2/pkg/menu/trayoptions.go +++ b/v2/pkg/menu/trayoptions.go @@ -1,18 +1,8 @@ package menu -type TrayType string - -const ( - TrayIcon TrayType = "icon" - TrayLabel TrayType = "label" -) - // TrayOptions are the options type TrayOptions struct { - // Type is the type of tray item we want - Type TrayType - - // Label is what is displayed initially when the type is TrayLabel + // Label is the text we wish to display in the tray Label string // Icon is the name of the tray icon we wish to display. diff --git a/v2/test/kitchensink/main.go b/v2/test/kitchensink/main.go index 83f906514..fe0c5012d 100644 --- a/v2/test/kitchensink/main.go +++ b/v2/test/kitchensink/main.go @@ -29,8 +29,6 @@ func main() { TitleBar: mac.TitleBarHiddenInset(), Menu: createApplicationMenu(), Tray: &menu.TrayOptions{ - //Type: menu.TrayLabel, - Type: menu.TrayIcon, Label: "Hi Go BitBar!", Icon: "light", Menu: createApplicationTray(), diff --git a/v2/test/kitchensink/tray.go b/v2/test/kitchensink/tray.go index 8c387f033..bd53a6592 100644 --- a/v2/test/kitchensink/tray.go +++ b/v2/test/kitchensink/tray.go @@ -44,19 +44,18 @@ func (t *Tray) WailsInit(runtime *wails.Runtime) error { t.runtime.Window.Unminimise() }) + // Auto switch between light / dark tray icons t.runtime.Events.OnThemeChange(func(darkMode bool) { if darkMode { - //t.runtime.Tray.SetIcon("light") - println("\n\n\n\n\n\nSET ICON TO LIGHT\n\n\n\n") + t.runtime.Tray.SetIcon("light") return } - //t.runtime.SetIcon("dark") - println("\n\n\n\n\n\nSET ICON TO DARK\n\n\n\n\n") + t.runtime.Tray.SetIcon("dark") }) // Start ticker - //go t.startTicker() + go t.startTicker() return nil }