Bug Report
Both the GUI menu bar and TUI menu are non-functional. Clicking on GUI menu bar items produces no response, and the TUI menu bar items are not rendered/dispatched correctly.
Reproduction
GUI:
- Start neomacs in GUI mode
- Observe the menu bar with items (File, Edit, Options, Buffers, Tools, Help)
- Click on any menu bar item
- Expected: A dropdown/popup menu appears
- Actual: Nothing happens
TUI:
- Start neomacs in TUI mode (
neomacs -nw)
- Row 0 should show menu bar items like "File Edit Options ..."
- Press F10 to trigger
tmm-menubar
- Expected:
tmm-menubar menu appears
- Actual: Menu items may not render correctly on row 0, or F10 does not trigger tmm-menubar
Root Cause Analysis
Bug 1: resolve_menu_bar_submenu only checks global-map, not local-map
In neovm-core/src/keyboard.rs, the resolve_menu_bar_submenu function only looks up the submenu keymap in global-map's [menu-bar] sub-keymap. It does not check the current buffer's local map (major-mode map).
This means:
collect_menu_bar_entries() collects key names from BOTH global and local maps (e.g., Lisp-Interaction from lisp-interaction-mode-map)
resolve_menu_bar_submenu() only looks in the global-map, so local-map entries fail to resolve → returns NIL → popup is never shown
Even for global items like File/Edit, this creates an inconsistency with how GNU Emacs resolves menu-bar entries.
Bug 2: TTY menu bar rendering may not work in all configurations
The TUI comparison tests (neomacs-tui-tests/tests/menus.rs) show that neomacs row 0 is empty while GNU Emacs shows "File Edit Options Buffers Tools Lisp-Interaction Help". This may be due to the neomacs binary failing to load its runtime image in the test environment.
Fix
The fix updates resolve_menu_bar_submenu to walk the active keymaps in the same order as collect_menu_bar_entries — global-map first, then the current buffer's local map. This mirrors GNU Emacs's x_activate_menubar / lw_popup_menu behavior where major-mode menu entries are resolved correctly.
GNU Emacs Semantics
GNU Emacs keyboard.c:menu_bar_items walks both the global map and the local map to collect menu items. The corresponding submenu resolution in x_activate_menubar also checks both maps. Neomacs must have 100% same semantics.
Test Evidence
The TUI test menu_bar_displays_top_level_items shows:
GNU row 0: |File Edit Options Buffers Tools Lisp-Interaction Help|
NEO row 0: || (empty)
The fix adds two new unit tests:
resolve_menu_bar_submenu_finds_local_map_entry - verifies local-map entries resolve
resolve_menu_bar_submenu_global_map_takes_precedence_over_local - verifies global-map wins on conflict
Bug Report
Both the GUI menu bar and TUI menu are non-functional. Clicking on GUI menu bar items produces no response, and the TUI menu bar items are not rendered/dispatched correctly.
Reproduction
GUI:
TUI:
neomacs -nw)tmm-menubartmm-menubarmenu appearsRoot Cause Analysis
Bug 1:
resolve_menu_bar_submenuonly checks global-map, not local-mapIn
neovm-core/src/keyboard.rs, theresolve_menu_bar_submenufunction only looks up the submenu keymap inglobal-map's[menu-bar]sub-keymap. It does not check the current buffer's local map (major-mode map).This means:
collect_menu_bar_entries()collects key names from BOTH global and local maps (e.g.,Lisp-Interactionfromlisp-interaction-mode-map)resolve_menu_bar_submenu()only looks in the global-map, so local-map entries fail to resolve → returns NIL → popup is never shownEven for global items like File/Edit, this creates an inconsistency with how GNU Emacs resolves menu-bar entries.
Bug 2: TTY menu bar rendering may not work in all configurations
The TUI comparison tests (
neomacs-tui-tests/tests/menus.rs) show that neomacs row 0 is empty while GNU Emacs shows "File Edit Options Buffers Tools Lisp-Interaction Help". This may be due to the neomacs binary failing to load its runtime image in the test environment.Fix
The fix updates
resolve_menu_bar_submenuto walk the active keymaps in the same order ascollect_menu_bar_entries— global-map first, then the current buffer's local map. This mirrors GNU Emacs'sx_activate_menubar/lw_popup_menubehavior where major-mode menu entries are resolved correctly.GNU Emacs Semantics
GNU Emacs
keyboard.c:menu_bar_itemswalks both the global map and the local map to collect menu items. The corresponding submenu resolution inx_activate_menubaralso checks both maps. Neomacs must have 100% same semantics.Test Evidence
The TUI test
menu_bar_displays_top_level_itemsshows:The fix adds two new unit tests:
resolve_menu_bar_submenu_finds_local_map_entry- verifies local-map entries resolveresolve_menu_bar_submenu_global_map_takes_precedence_over_local- verifies global-map wins on conflict