@@ -381,6 +381,22 @@ void erase_all_menu_parts(lua_State *L, NSStatusItem *statusItem) {
381381 return ;
382382}
383383
384+ // Prepare an existing menu on a menubar item for reuse or create a new menu
385+ NSMenu * create_or_reuse_menu (lua_State *L, NSStatusItem *statusItem, NSString *menuTitle) {
386+ NSMenu *menu = [statusItem menu ];
387+ if (menu) {
388+ erase_menu_delegate (L, menu);
389+ erase_menu_items (L, menu);
390+
391+ [statusItem setMenu: nil ];
392+ [menu setTitle: menuTitle];
393+ return menu;
394+ }
395+
396+ // no existing menu
397+ return [[NSMenu alloc ] initWithTitle: menuTitle];
398+ }
399+
384400// Create and push a lua geometry rect
385401static void geom_pushrect (lua_State* L, NSRect rect) {
386402 lua_newtable (L);
@@ -753,13 +769,11 @@ static int menubarSetMenu(lua_State *L) {
753769 NSMenu *menu = nil ;
754770 HSMenubarItemMenuDelegate *delegate = nil ;
755771
756- // We always need to start by erasing any preexisting menu stuff
757- erase_all_menu_parts (L, statusItem);
758-
759772 switch (lua_type (L, 2 )) {
760773 case LUA_TTABLE:
761774 // This is a static menu, so we can just parse the table and the menu will be populated
762- menu = [[NSMenu alloc ] initWithTitle: @" HammerspoonMenuItemStaticMenu" ];
775+ menu = create_or_reuse_menu (L, statusItem, @" HammerspoonMenuItemStaticMenu" );
776+
763777 if (menu) {
764778 [menu setAutoenablesItems: NO ];
765779 parse_table (L, 2 , menu, menuBarItem->stateBoxImageSize );
@@ -773,7 +787,8 @@ static int menubarSetMenu(lua_State *L) {
773787
774788 case LUA_TFUNCTION:
775789 // This is a dynamic menu, so create a delegate object that will allow us to fetch a table whenever the menu is about to be displayed
776- menu = [[NSMenu alloc ] initWithTitle: @" HammerspoonMenuItemDynamicMenu" ];
790+ menu = create_or_reuse_menu (L, statusItem, @" HammerspoonMenuItemDynamicMenu" );
791+
777792 if (menu) {
778793 [menu setAutoenablesItems: NO ];
779794
@@ -787,7 +802,10 @@ static int menubarSetMenu(lua_State *L) {
787802 break ;
788803 }
789804
790- if (menu) {
805+ if (menu == nil ) {
806+ // clear out any previous menu
807+ erase_all_menu_parts (L, statusItem);
808+ } else {
791809 [statusItem setMenu: menu];
792810 if (delegate) {
793811 [menu setDelegate: delegate];
0 commit comments