From 5196a4fd2cf1507943c1fdfd8d3a598cb5d1c281 Mon Sep 17 00:00:00 2001 From: Brian Dwyer Date: Mon, 19 Dec 2022 16:24:34 -0500 Subject: [PATCH] Add support for removing a menu item Signed-off-by: Brian Dwyer --- systray.go | 8 ++++++++ systray.h | 1 + systray_darwin.go | 6 ++++++ systray_darwin.m | 13 +++++++++++++ systray_windows.go | 25 +++++++++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/systray.go b/systray.go index d0a0dfae..e9d2bb4c 100644 --- a/systray.go +++ b/systray.go @@ -203,6 +203,14 @@ func (item *MenuItem) Hide() { hideMenuItem(item) } +// Remove removes a menu item +func (item *MenuItem) Remove() { + removeMenuItem(item) + menuItemsLock.Lock() + delete(menuItems, item.id) + menuItemsLock.Unlock() +} + // Show shows a previously hidden menu item func (item *MenuItem) Show() { showMenuItem(item) diff --git a/systray.h b/systray.h index 1bc03460..4858eb4d 100644 --- a/systray.h +++ b/systray.h @@ -15,6 +15,7 @@ void setTooltip(char* tooltip); void add_or_update_menu_item(int menuId, int parentMenuId, char* title, char* tooltip, short disabled, short checked, short isCheckable); void add_separator(int menuId); void hide_menu_item(int menuId); +void remove_menu_item(int menuId); void show_menu_item(int menuId); void reset_menu(); void quit(); diff --git a/systray_darwin.go b/systray_darwin.go index 21fb0572..c730e616 100644 --- a/systray_darwin.go +++ b/systray_darwin.go @@ -127,6 +127,12 @@ func showMenuItem(item *MenuItem) { ) } +func removeMenuItem(item *MenuItem) { + C.remove_menu_item( + C.int(item.id), + ) +} + func resetMenu() { C.reset_menu() } diff --git a/systray_darwin.m b/systray_darwin.m index 268e1700..274ac513 100644 --- a/systray_darwin.m +++ b/systray_darwin.m @@ -203,6 +203,14 @@ - (void) show_menu_item:(NSNumber*) menuId } } +- (void) remove_menu_item:(NSNumber*) menuId +{ + NSMenuItem* menuItem = find_menu_item(menu, menuId); + if (menuItem != NULL) { + [menuItem.menu removeItem:menuItem]; + } +} + - (void) reset_menu { [self->menu removeAllItems]; @@ -312,6 +320,11 @@ void hide_menu_item(int menuId) { runInMainThread(@selector(hide_menu_item:), (id)mId); } +void remove_menu_item(int menuId) { + NSNumber *mId = [NSNumber numberWithInt:menuId]; + runInMainThread(@selector(remove_menu_item:), (id)mId); +} + void show_menu_item(int menuId) { NSNumber *mId = [NSNumber numberWithInt:menuId]; runInMainThread(@selector(show_menu_item:), (id)mId); diff --git a/systray_windows.go b/systray_windows.go index f6ce3060..1116725f 100644 --- a/systray_windows.go +++ b/systray_windows.go @@ -41,6 +41,7 @@ var ( pCreatePopupMenu = u32.NewProc("CreatePopupMenu") pCreateWindowEx = u32.NewProc("CreateWindowExW") pDefWindowProc = u32.NewProc("DefWindowProcW") + pDeleteMenu = u32.NewProc("DeleteMenu") pRemoveMenu = u32.NewProc("RemoveMenu") pDestroyWindow = u32.NewProc("DestroyWindow") pDispatchMessage = u32.NewProc("DispatchMessageW") @@ -673,6 +674,30 @@ func (t *winTray) addSeparatorMenuItem(menuItemId, parentId uint32) error { return nil } +func (t *winTray) removeMenuItem(menuItemId, parentId uint32) error { + if !wt.isReady() { + return ErrTrayNotReadyYet + } + + const MF_BYCOMMAND = 0x00000000 + const ERROR_SUCCESS syscall.Errno = 0 + + t.muMenus.RLock() + menu := uintptr(t.menus[parentId]) + t.muMenus.RUnlock() + res, _, err := pDeleteMenu.Call( + menu, + uintptr(menuItemId), + MF_BYCOMMAND, + ) + if res == 0 && err.(syscall.Errno) != ERROR_SUCCESS { + return err + } + t.delFromVisibleItems(parentId, menuItemId) + + return nil +} + func (t *winTray) hideMenuItem(menuItemId, parentId uint32) error { if !wt.isReady() { return ErrTrayNotReadyYet