5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-07 11:09:52 +08:00

Support changing tray icon at runtime

Support both icon & text in tray
This commit is contained in:
Lea Anthony 2020-12-24 10:05:55 +11:00
parent 8625e99625
commit f0c932713b
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
12 changed files with 67 additions and 40 deletions

View File

@ -36,5 +36,6 @@ extern void UpdateMenu(void *app, char *menuAsJSON);
extern void UpdateTray(void *app, char *menuAsJSON); extern void UpdateTray(void *app, char *menuAsJSON);
extern void UpdateContextMenus(void *app, char *contextMenusAsJSON); extern void UpdateContextMenus(void *app, char *contextMenusAsJSON);
extern void UpdateTrayLabel(void *app, const char *label); extern void UpdateTrayLabel(void *app, const char *label);
extern void UpdateTrayIcon(void *app, const char *label);
#endif #endif

View File

@ -188,10 +188,15 @@ func (c *Client) UpdateTray(menu *menu.Menu) {
} }
C.UpdateTray(c.app.app, c.app.string2CString(string(trayMenuJSON))) C.UpdateTray(c.app.app, c.app.string2CString(string(trayMenuJSON)))
} }
func (c *Client) UpdateTrayLabel(label string) { func (c *Client) UpdateTrayLabel(label string) {
C.UpdateTrayLabel(c.app.app, c.app.string2CString(label)) 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) { func (c *Client) UpdateContextMenus(contextMenus *menu.ContextMenus) {
// Guard against nil contextMenus // Guard against nil contextMenus

View File

@ -78,6 +78,14 @@
#define NSEventTypeRightMouseDown 3 #define NSEventTypeRightMouseDown 3
#define NSEventTypeRightMouseUp 4 #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 // References to assets
extern const unsigned char *assets[]; extern const unsigned char *assets[];
@ -219,9 +227,9 @@ struct Application {
// Tray // Tray
const char *trayMenuAsJSON; const char *trayMenuAsJSON;
const char *trayType;
const char *trayLabel; const char *trayLabel;
const char *trayIconName; const char *trayIconName;
int trayIconPosition;
JsonNode *processedTrayMenu; JsonNode *processedTrayMenu;
id statusItem; id statusItem;
@ -823,9 +831,9 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
// Tray // Tray
result->trayMenuAsJSON = NULL; result->trayMenuAsJSON = NULL;
result->trayType = NULL;
result->trayLabel = NULL; result->trayLabel = NULL;
result->trayIconName = NULL; result->trayIconName = NULL;
result->trayIconPosition = NSImageLeft; // Left of the text by default
result->processedTrayMenu = NULL; result->processedTrayMenu = NULL;
result->statusItem = 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 // 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->trayMenuAsJSON = trayMenuAsJSON;
app->trayType = trayType;
app->trayLabel = trayLabel; app->trayLabel = trayLabel;
app->trayIconName = trayIconName; app->trayIconName = trayIconName;
} }
@ -2267,6 +2274,13 @@ void UpdateTrayLabel(struct Application *app, const char *label) {
msg(statusBarButton, s("setTitle:"), str(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) { void processTrayIconData(struct Application *app) {
unsigned int count = 0; unsigned int count = 0;
@ -2312,18 +2326,16 @@ void parseTrayData(struct Application *app) {
statusItem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength); statusItem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength);
app->statusItem = statusItem; app->statusItem = statusItem;
msg(statusItem, s("retain")); 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
// Get the icon if ( app->trayIconName != NULL ) {
if ( app->trayIconName != NULL ) { UpdateTrayIcon(app, app->trayIconName);
id trayImage = hashmap_get(&trayIconCache, app->trayIconName, strlen(app->trayIconName));
msg(statusBarButton, s("setImage:"), trayImage);
}
} }
if( STREQ(app->trayType, "label") ) {
// If we have a tray icon if( app->trayLabel != NULL ) {
msg(statusBarButton, s("setTitle:"), str(app->trayLabel)); UpdateTrayLabel(app, app->trayLabel);
} }
} }
@ -2365,12 +2377,6 @@ void parseTrayData(struct Application *app) {
processRadioGroup(radioGroup, &menuItemMapForTrayMenu, &radioGroupMapForTrayMenu); 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); msg(statusItem, s("setMenu:"), traymenu);
} }

View File

@ -99,7 +99,7 @@ func (a *Application) processPlatformSettings() error {
if err != nil { if err != nil {
return err 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 // Process context menus

View File

@ -13,7 +13,7 @@ extern void SetAppearance(void *, const char *);
extern void WebviewIsTransparent(void *); extern void WebviewIsTransparent(void *);
extern void WindowBackgroundIsTranslucent(void *); extern void WindowBackgroundIsTranslucent(void *);
extern void SetMenu(void *, const char *); 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 *); extern void SetContextMenus(void *, const char *);
#endif #endif

View File

@ -34,6 +34,7 @@ type Client interface {
UpdateMenu(menu *menu.Menu) UpdateMenu(menu *menu.Menu)
UpdateTray(menu *menu.Menu) UpdateTray(menu *menu.Menu)
UpdateTrayLabel(label string) UpdateTrayLabel(label string)
UpdateTrayIcon(name string)
UpdateContextMenus(contextMenus *menu.ContextMenus) UpdateContextMenus(contextMenus *menu.ContextMenus)
} }

View File

@ -523,6 +523,21 @@ func (d *Dispatcher) processTrayMessage(result *servicebus.Message) {
client.frontend.UpdateTrayLabel(updatedLabel) 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: default:
d.logger.Error("Unknown menufrontend command: %s", command) d.logger.Error("Unknown menufrontend command: %s", command)
} }

View File

@ -13,6 +13,7 @@ type Tray interface {
GetByID(menuID string) *menu.MenuItem GetByID(menuID string) *menu.MenuItem
RemoveByID(id string) bool RemoveByID(id string) bool
SetLabel(label string) SetLabel(label string)
SetIcon(name string)
} }
type trayRuntime struct { type trayRuntime struct {
@ -43,6 +44,9 @@ func (t *trayRuntime) Update() {
func (t *trayRuntime) SetLabel(label string) { func (t *trayRuntime) SetLabel(label string) {
t.bus.Publish("tray:setlabel", label) 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 { func (t *trayRuntime) GetByID(menuID string) *menu.MenuItem {
return t.trayMenu.Menu.GetByID(menuID) return t.trayMenu.Menu.GetByID(menuID)

View File

@ -126,6 +126,14 @@ func (t *Tray) Start() error {
// Notify frontend of menu change // Notify frontend of menu change
t.bus.Publish("trayfrontend:setlabel", updatedLabel) 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: default:
t.logger.Error("unknown tray message: %+v", menuMessage) t.logger.Error("unknown tray message: %+v", menuMessage)
} }

View File

@ -1,18 +1,8 @@
package menu package menu
type TrayType string
const (
TrayIcon TrayType = "icon"
TrayLabel TrayType = "label"
)
// TrayOptions are the options // TrayOptions are the options
type TrayOptions struct { type TrayOptions struct {
// Type is the type of tray item we want // Label is the text we wish to display in the tray
Type TrayType
// Label is what is displayed initially when the type is TrayLabel
Label string Label string
// Icon is the name of the tray icon we wish to display. // Icon is the name of the tray icon we wish to display.

View File

@ -29,8 +29,6 @@ func main() {
TitleBar: mac.TitleBarHiddenInset(), TitleBar: mac.TitleBarHiddenInset(),
Menu: createApplicationMenu(), Menu: createApplicationMenu(),
Tray: &menu.TrayOptions{ Tray: &menu.TrayOptions{
//Type: menu.TrayLabel,
Type: menu.TrayIcon,
Label: "Hi Go BitBar!", Label: "Hi Go BitBar!",
Icon: "light", Icon: "light",
Menu: createApplicationTray(), Menu: createApplicationTray(),

View File

@ -44,19 +44,18 @@ func (t *Tray) WailsInit(runtime *wails.Runtime) error {
t.runtime.Window.Unminimise() t.runtime.Window.Unminimise()
}) })
// Auto switch between light / dark tray icons
t.runtime.Events.OnThemeChange(func(darkMode bool) { t.runtime.Events.OnThemeChange(func(darkMode bool) {
if darkMode { if darkMode {
//t.runtime.Tray.SetIcon("light") t.runtime.Tray.SetIcon("light")
println("\n\n\n\n\n\nSET ICON TO LIGHT\n\n\n\n")
return return
} }
//t.runtime.SetIcon("dark") t.runtime.Tray.SetIcon("dark")
println("\n\n\n\n\n\nSET ICON TO DARK\n\n\n\n\n")
}) })
// Start ticker // Start ticker
//go t.startTicker() go t.startTicker()
return nil return nil
} }