Skip to content

Commit

Permalink
Merge pull request #34 from bdwyertech/remove-menu-item
Browse files Browse the repository at this point in the history
Add support for removing a menu item
  • Loading branch information
andydotxyz authored Jan 16, 2023
2 parents 3cfcb36 + 31f066d commit e79f9a4
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 9 deletions.
8 changes: 8 additions & 0 deletions systray.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions systray.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
6 changes: 6 additions & 0 deletions systray_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
35 changes: 26 additions & 9 deletions systray_darwin.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -266,19 +274,23 @@ void runInMainThread(SEL method, id object) {

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);
@autoreleasepool {
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, 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]);
@autoreleasepool {
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]);
}
}

void setTitle(char* ctitle) {
Expand Down Expand Up @@ -312,6 +324,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);
Expand Down
36 changes: 36 additions & 0 deletions systray_menu_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,42 @@ func findSubLayout(id int32, vals []dbus.Variant) (*menuLayout, bool) {
return nil, false
}

func removeSubLayout(id int32, vals []dbus.Variant) ([]dbus.Variant, bool) {
for idx, i := range vals {
item := i.Value().(*menuLayout)
if item.V0 == id {
return append(vals[:idx], vals[idx+1:]...), true
}

if len(item.V2) > 0 {
if child, removed := removeSubLayout(id, item.V2); removed {
return child, true
}
}
}

return vals, false
}

func removeMenuItem(item *MenuItem) {
instance.menuLock.Lock()
defer instance.menuLock.Unlock()

parent := instance.menu
if item.parent != nil {
m, ok := findLayout(int32(item.parent.id))
if !ok {
return
}
parent = m
}

if items, removed := removeSubLayout(int32(item.id), parent.V2); removed {
parent.V2 = items
refresh()
}
}

func hideMenuItem(item *MenuItem) {
instance.menuLock.Lock()
defer instance.menuLock.Unlock()
Expand Down
33 changes: 33 additions & 0 deletions systray_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1051,6 +1076,14 @@ func hideMenuItem(item *MenuItem) {
}
}

func removeMenuItem(item *MenuItem) {
err := wt.removeMenuItem(uint32(item.id), item.parentId())
if err != nil {
log.Printf("systray error: unable to removeMenuItem: %s\n", err)
return
}
}

func showMenuItem(item *MenuItem) {
addOrUpdateMenuItem(item)
}
Expand Down

0 comments on commit e79f9a4

Please sign in to comment.