feat: GTK tab/editor context menus use engine-drawn rendering - #137
Merged
Conversation
Adds a Cairo-based context menu renderer in gtk/draw.rs that draws from render::ContextMenuPanel — the same data TUI and Win-GUI use. Wired into the draw loop but currently no-op because GTK still closes the engine context menu before drawing (PopoverMenu is still active). The full migration (removing PopoverMenu, keeping engine context menu alive, adding click handling) is a follow-up. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrates GTK tab-bar and editor right-click context menus from native PopoverMenu widgets to engine-driven rendering via draw_context_menu_popup(). Tab and editor right-clicks now call engine.open_*_context_menu() with char-cell coordinates, keeping the engine context menu alive for rendering. Changes: - Tab right-click: engine.open_tab_context_menu() instead of PopoverMenu - Editor right-click: engine.open_editor_context_menu() instead of PopoverMenu - Left-click handling: resolve_context_menu_click() dismisses or selects - Keyboard handling: Escape dismisses, j/k navigate, Enter confirms - draw_context_menu_popup() renders from ContextMenuPanel (same as TUI/Win-GUI) Explorer right-click still uses PopoverMenu (tied to GTK TreeView widget). Old handler methods kept with #[allow(dead_code)] for reference. Partial #135 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds EventControllerMotion on the drawing area that updates context_menu.selected as the mouse moves over items, triggering a redraw for highlight feedback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The motion callback fires during GTK event loop iterations where the engine RefCell may already be borrowed by the draw function. Using try_borrow_mut() skips the hover update gracefully instead of panicking. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Motion callback uses try_borrow()/try_borrow_mut() with separate scopes to avoid RefCell panics in GTK's extern "C" callback - No unwrap() calls that could panic across FFI boundary - Updated CLAUDE.md: don't push until user approves smoke tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the separate EventControllerMotion that was causing RefCell panics across GTK's extern "C" boundary. Instead, add hover logic to the existing mouse_pos_cell motion handler — uses try_borrow_mut and computes the new selection index from an immutable borrow before mutating, avoiding any unwrap() calls in the FFI callback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…backs Mouse hover highlighting in engine-drawn context menus causes RefCell panics across GTK's extern "C" FFI boundary. Removed all hover logic. Context menus still work via click and keyboard (j/k/Enter/Escape). Hover can be revisited when the drawing architecture avoids holding engine borrows during GTK signal dispatch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of mutating engine state in a motion callback (which causes RefCell panics across GTK's extern C boundary), compute the hovered item inside draw_context_menu_popup() from the existing mouse_pos_cell. Motion callback just triggers queue_draw() when a context menu is open (using try_borrow to safely check). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- resolve_context_menu_click: use saturating_sub to prevent overflow when click_row == py (clicking on the top border) - draw_context_menu_popup: only highlight when mouse is directly over an item; when mouse is on separator/border inside popup, no highlight; when mouse is outside popup, fall back to keyboard selection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Motion callback updates engine.context_menu.selected via try_borrow_mut so the selection persists when mouse leaves the popup - Draw function uses hover_idx (from mouse_pos) with fallback to cm.selected_idx — keeps last-hovered item highlighted when mouse exits - Disabled items already use theme.line_number_fg (dim grey) vs theme.fuzzy_fg (normal text) for visual distinction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use fuzzy_fg.darken(0.5) for disabled items instead of line_number_fg which was too similar to the normal text color on some themes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 18, 2026
JDonaghy
added a commit
that referenced
this pull request
May 16, 2026
…#395) The engine-drawn context-menu path (paint at draw.rs::draw_context_menu_popup, click dispatch + hover via cached ContextMenuLayout at gtk/mod.rs:6022, keyboard via engine::handle_context_menu_key) was fully wired in earlier work (#137, #210/#425) but the editor "..." action menu kept building a native gtk4::PopoverMenu on top. Two right-click handlers (handle_tab_right_click, handle_editor_right_click) had already been replaced by Msg::TabRightClick (mod.rs:4014) / Msg::EditorRightClick (mod.rs:4042) but their bodies were left behind with #[allow(dead_code)]. - click.rs::handle_mouse_click derives (col, row) from the click's pixel coords when opening the editor action menu, so the engine's ContextMenuState anchor lands under the "..." button instead of (0, 0). - gtk/mod.rs drops the show_action_menu_popover call branch; the engine-drawn renderer + click dispatch take over from there. - Deletes 3 unused functions (~497 lines): show_action_menu_popover, handle_tab_right_click, handle_editor_right_click. Explorer context menu (show_explorer_context_menu) stays on native PopoverMenu in this PR — engine-drawn ctx menu paints on the editor DA, but explorer right-clicks happen on the explorer DA (separate GTK widget, independent coord system). Cross-DA handling tracked in #426. Refs #395. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JDonaghy
added a commit
that referenced
this pull request
May 16, 2026
…#395) The engine-drawn context-menu path (paint at draw.rs::draw_context_menu_popup, click dispatch + hover via cached ContextMenuLayout at gtk/mod.rs:6022, keyboard via engine::handle_context_menu_key) was fully wired in earlier work (#137, #210/#425) but the editor "..." action menu kept building a native gtk4::PopoverMenu on top. Two right-click handlers (handle_tab_right_click, handle_editor_right_click) had already been replaced by Msg::TabRightClick (mod.rs:4014) / Msg::EditorRightClick (mod.rs:4042) but their bodies were left behind with #[allow(dead_code)]. - click.rs::handle_mouse_click derives (col, row) from the click's pixel coords when opening the editor action menu, so the engine's ContextMenuState anchor lands under the "..." button instead of (0, 0). - gtk/mod.rs drops the show_action_menu_popover call branch; the engine-drawn renderer + click dispatch take over from there. - Deletes 3 unused functions (~497 lines): show_action_menu_popover, handle_tab_right_click, handle_editor_right_click. Explorer context menu (show_explorer_context_menu) stays on native PopoverMenu in this PR — engine-drawn ctx menu paints on the editor DA, but explorer right-clicks happen on the explorer DA (separate GTK widget, independent coord system). Cross-DA handling tracked in Refs #395. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
draw_context_menu_popup()instead of nativePopoverMenuwidgetsresolve_context_menu_click()from Hit regions for context menus + dialogs #43j/kto move,Enterto confirm,Escapeto dismissBefore/After
Before: Native GTK PopoverMenu with OS-styled items
After: Engine-drawn popup matching TUI/Win-GUI visual style — consistent across all backends
Test plan
cargo clippy -- -D warnings— cleanSmoke test (GTK)
j/kto navigate,Enterto confirm,Escapeto dismissPartial #135
🤖 Generated with Claude Code