diff --git a/example/main.go b/example/main.go index 817d631..c6dbaae 100644 --- a/example/main.go +++ b/example/main.go @@ -21,7 +21,7 @@ func main() { } func onReady() { - systray.SetIcon(icon.Data) + systray.SetTemplateIcon(icon.Data, icon.Data) systray.SetTitle("Awesome App") systray.SetTooltip("Lantern") mQuitOrig := systray.AddMenuItem("Quit", "Quit the whole app") @@ -34,12 +34,15 @@ func onReady() { // We can manipulate the systray in other goroutines go func() { - systray.SetIcon(icon.Data) + systray.SetTemplateIcon(icon.Data, icon.Data) systray.SetTitle("Awesome App") systray.SetTooltip("Pretty awesome棒棒嗒") mChange := systray.AddMenuItem("Change Me", "Change Me") mChecked := systray.AddMenuItem("Unchecked", "Check Me") mEnabled := systray.AddMenuItem("Enabled", "Enabled") + // Sets the icon of a menu item. Only available on Mac. + mEnabled.SetTemplateIcon(icon.Data, icon.Data) + systray.AddMenuItem("Ignored", "Ignored") mUrl := systray.AddMenuItem("Open UI", "my home") mQuit := systray.AddMenuItem("退出", "Quit the whole app") diff --git a/systray.h b/systray.h index 128315f..29ba436 100644 --- a/systray.h +++ b/systray.h @@ -1,10 +1,12 @@ +#include "stdbool.h" + extern void systray_ready(); extern void systray_on_exit(); extern void systray_menu_item_selected(int menu_id); int nativeLoop(char* title, int width, int height); -void setIcon(const char* iconBytes, int length); -void setMenuItemIcon(const char* iconBytes, int length, int menuId); +void setIcon(const char* iconBytes, int length, bool template); +void setMenuItemIcon(const char* iconBytes, int length, int menuId, bool template); void setTitle(char* title); void setTooltip(char* tooltip); void configureAppWindow(char* title, int width, int height); diff --git a/systray_darwin.go b/systray_darwin.go new file mode 100644 index 0000000..568edab --- /dev/null +++ b/systray_darwin.go @@ -0,0 +1,37 @@ +package systray + +/* +#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc +#cgo darwin LDFLAGS: -framework Cocoa -framework WebKit + +#include "systray.h" +*/ +import "C" + +import ( + "unsafe" +) + +// SetTemplateIcon sets the systray icon as a template icon (on Mac), falling back +// to a regular icon on other platforms. +// templateIconBytes and regularIconBytes should be the content of .ico for windows and +// .ico/.jpg/.png for other platforms. +func SetTemplateIcon(templateIconBytes []byte, regularIconBytes []byte) { + cstr := (*C.char)(unsafe.Pointer(&templateIconBytes[0])) + C.setIcon(cstr, (C.int)(len(templateIconBytes)), true) +} + +// SetIcon sets the icon of a menu item. Only works on macOS and Windows. +// iconBytes should be the content of .ico/.jpg/.png +func (item *MenuItem) SetIcon(iconBytes []byte) { + SetTemplateIcon(iconBytes, iconBytes) +} + +// SetTemplateIcon sets the icon of a menu item as a template icon (on macOS). On Windows, it +// falls back to the regular icon bytes and on Linux it does nothing. +// templateIconBytes and regularIconBytes should be the content of .ico for windows and +// .ico/.jpg/.png for other platforms. +func (item *MenuItem) SetTemplateIcon(templateIconBytes []byte, regularIconBytes []byte) { + cstr := (*C.char)(unsafe.Pointer(&templateIconBytes[0])) + C.setMenuItemIcon(cstr, (C.int)(len(templateIconBytes)), C.int(item.id), true) +} \ No newline at end of file diff --git a/systray_darwin.m b/systray_darwin.m index e0150c7..84a869f 100644 --- a/systray_darwin.m +++ b/systray_darwin.m @@ -204,18 +204,19 @@ void runInMainThread(SEL method, id object) { waitUntilDone: YES]; } -void setIcon(const char* iconBytes, int length) { +void setIcon(const char* iconBytes, int length, bool template) { NSData* buffer = [NSData dataWithBytes: iconBytes length:length]; NSImage *image = [[NSImage alloc] initWithData:buffer]; [image setSize:NSMakeSize(16, 16)]; + image.template = template; runInMainThread(@selector(setIcon:), (id)image); } -void setMenuItemIcon(const char* iconBytes, int length, int menuId) { +void setMenuItemIcon(const char* iconBytes, int length, int menuId, bool template) { NSData* buffer = [NSData dataWithBytes: iconBytes length:length]; NSImage *image = [[NSImage alloc] initWithData:buffer]; [image setSize:NSMakeSize(16, 16)]; - + image.template = template; NSNumber *mId = [NSNumber numberWithInt:menuId]; runInMainThread(@selector(setMenuItemIcon:), @[image, (id)mId]); } diff --git a/systray_linux.c b/systray_linux.c index 7b045f2..4439047 100644 --- a/systray_linux.c +++ b/systray_linux.c @@ -172,7 +172,7 @@ gboolean do_quit(gpointer data) { return FALSE; } -void setIcon(const char* iconBytes, int length) { +void setIcon(const char* iconBytes, int length, bool template) { GBytes* bytes = g_bytes_new_static(iconBytes, length); g_idle_add(do_set_icon, bytes); } @@ -186,7 +186,7 @@ void setTooltip(char* ctooltip) { free(ctooltip); } -void setMenuItemIcon(const char* iconBytes, int length, int menuId) { +void setMenuItemIcon(const char* iconBytes, int length, int menuId, bool template) { } void add_or_update_menu_item(int menu_id, char* title, char* tooltip, short disabled, short checked) { diff --git a/systray_linux.go b/systray_linux.go new file mode 100644 index 0000000..1f508c7 --- /dev/null +++ b/systray_linux.go @@ -0,0 +1,29 @@ +package systray + +/* +#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc +#cgo darwin LDFLAGS: -framework Cocoa -framework WebKit + +#include "systray.h" +*/ +import "C" + +// SetTemplateIcon sets the systray icon as a template icon (on macOS), falling back +// to a regular icon on other platforms. +// templateIconBytes and iconBytes should be the content of .ico for windows and +// .ico/.jpg/.png for other platforms. +func SetTemplateIcon(templateIconBytes []byte, regularIconBytes []byte) { + SetIcon(regularIconBytes) +} + +// SetIcon sets the icon of a menu item. Only works on macOS and Windows. +// iconBytes should be the content of .ico/.jpg/.png +func (item *MenuItem) SetIcon(iconBytes []byte) { +} + +// SetTemplateIcon sets the icon of a menu item as a template icon (on macOS). On Windows, it +// falls back to the regular icon bytes and on Linux it does nothing. +// templateIconBytes and regularIconBytes should be the content of .ico for windows and +// .ico/.jpg/.png for other platforms. +func (item *MenuItem) SetTemplateIcon(templateIconBytes []byte, regularIconBytes []byte) { +} diff --git a/systray_nonwindows.go b/systray_nonwindows.go index 598df9e..96337ff 100644 --- a/systray_nonwindows.go +++ b/systray_nonwindows.go @@ -35,7 +35,7 @@ func ShowAppWindow(url string) { // for other platforms. func SetIcon(iconBytes []byte) { cstr := (*C.char)(unsafe.Pointer(&iconBytes[0])) - C.setIcon(cstr, (C.int)(len(iconBytes))) + C.setIcon(cstr, (C.int)(len(iconBytes)), false) } // SetTitle sets the systray title, only available on Mac. @@ -67,13 +67,6 @@ func addOrUpdateMenuItem(item *MenuItem) { ) } -// SetIcon sets the icon of a menu item. Only available on Mac. -// iconBytes should be the content of .ico/.jpg/.png -func (item *MenuItem) SetIcon(iconBytes []byte) { - cstr := (*C.char)(unsafe.Pointer(&iconBytes[0])) - C.setMenuItemIcon(cstr, (C.int)(len(iconBytes)), C.int(item.id)) -} - func addSeparator(id int32) { C.add_separator(C.int(id)) } diff --git a/systray_windows.go b/systray_windows.go index eda870b..03dc032 100644 --- a/systray_windows.go +++ b/systray_windows.go @@ -104,6 +104,14 @@ func SetIcon(iconBytes []byte) { } } +// SetTemplateIcon sets the systray icon as a template icon (on macOS), falling back +// to a regular icon on other platforms. +// templateIconBytes and iconBytes should be the content of .ico for windows and +// .ico/.jpg/.png for other platforms. +func SetTemplateIcon(templateIconBytes []byte, regularIconBytes []byte) { + SetIcon(regularIconBytes) +} + // SetTitle sets the systray title, only available on Mac. func SetTitle(title string) { // not supported on Windows @@ -160,6 +168,8 @@ func addOrUpdateMenuItem(item *MenuItem) { } } +// SetIcon sets the icon of a menu item. Only works on macOS and Windows. +// iconBytes should be the content of .ico/.jpg/.png func (item *MenuItem) SetIcon(iconBytes []byte) { md5 := md5.Sum(iconBytes) filename := fmt.Sprintf("systray.%x.ico", md5) @@ -181,6 +191,14 @@ func (item *MenuItem) SetIcon(iconBytes []byte) { actions[item.id].SetImage(icon) } +// SetTemplateIcon sets the icon of a menu item as a template icon (on macOS). On Windows, it +// falls back to the regular icon bytes and on Linux it does nothing. +// templateIconBytes and regularIconBytes should be the content of .ico for windows and +// .ico/.jpg/.png for other platforms. +func (item *MenuItem) SetTemplateIcon(templateIconBytes []byte, regularIconBytes []byte) { + item.SetIcon(regularIconBytes) +} + func addSeparator(id int32) { action := walk.NewSeparatorAction() if err := notifyIcon.ContextMenu().Actions().Add(action); err != nil {