refactor: GTK action menu engine-drawn; drop dead right-click bodies (#395) - #427
Conversation
Smoke test checklist (for the desktop agent picking this up)1. Quality gatecargo fmt
cargo clippy -- -D warnings
cargo test --no-default-features --lib
cargo buildAll four must be green before merging. The 2. Action menu smoke (the actual migrated piece)This is the only behavior change in the PR. Everything else is dead-code removal.
3. Regression checks — context menus that were already engine-drawnThese weren't touched by this PR but exercise the same engine-drawn path; verify nothing drifted:
4. NOT changed in this PR — explorer right-click
If the explorer menu looks visually different or items don't fire, that's a regression. The explorer migration is deferred to #426. 5. Branch ready-to-merge stateIf everything above passes, this PR is ready for merge to develop. The CLAUDE.md workflow step 5 then says: when merged, run |
…#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>
3b3c9ef to
c476b67
Compare
PR #427 landed; ~497 lines of native-popover dead code removed. Filed quadraui#205 (selection bg obscures top/bottom border), vimcode#434 (menu opens AT button row, not below), vimcode#435 (keyboard nav dead until click — same class as #273) as follow-ups. #395 stays open until #426 (explorer right-click). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The editor tab bar `…` action menu opened at the row of the button itself (overlapping the tab row) instead of below it. After PR #427 migrated the action menu from gtk4::PopoverMenu to the engine-drawn quadraui::ContextMenu, the click coords were anchored as-is and the adapter never set a placement, so quadraui defaulted to AnchorPoint (menu top-left == click point). TUI had been masking the same bug with a `row + 1` hack at the call site. Take option 1 from the issue: thread the trigger element's height through the engine and use ContextMenuPlacement::Below. - ContextMenuState gains `trigger_height: u16` (cells). 0 = right-click flow → AnchorPoint; non-zero = dropdown-style → Below. - open_editor_action_menu(group_id, x, y, trigger_height) — new arg. The four right-click open_* functions default trigger_height to 0. - ContextMenuPanel + render builder propagate the field. - context_menu_panel_to_quadraui_context_menu sets placement based on trigger_height. - Both backends switch from `.layout()` to `.layout_at()` with an anchor Rect carrying the trigger height in their native unit (line_height px for GTK, 1 cell for TUI). - GTK click handler computes trigger height from tab_row_height_px / line_height (ceiled) — about 2 cells. The sub-cell rounding leaves a small gap below the button rather than overlap; cleaning that up is #168's job. - TUI call sites drop the `row + 1` hack and pass row + height=1. Auto-flip to Above when there's no room below is handled by quadraui's layout_at; vimcode gets it for free. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mServices Msg::OpenFileDialog and Msg::SaveWorkspaceAsDialog now call backend.services().show_file_open_dialog()/show_file_save_dialog() (quadraui#427, now shipped) instead of constructing gtk4::FileDialog in-line. dispatch() has no `backend` in scope, so the request is stashed in a new PendingFileDialog Cell and drained in tick(), which does receive the runner-owned `backend: &mut dyn quadraui::Backend` — the same instance whose PlatformServices pump_depth is wired to the runner's own event controllers, unlike App's separate self.backend field (used for modal-stack/drag-state), which must NOT be used for this (unshared pump_depth would reintroduce the #427 double-borrow panic). Msg::OpenFolderDialog stays on direct gtk4::FileDialog for now: quadraui::PlatformServices has no folder-select dialog mode yet (only file-open/file-save). That gap needs a new quadraui issue before the third call site can migrate. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Refs #395 (does not close — explorer follow-up is #426).
Files
Test plan
Smoke checklist added as a PR comment so the validating agent has it inline.
🤖 Generated with Claude Code