Summary
Once quadraui#349 lands (cross-group tab drag-and-drop in TabGroupController), replace vimcode's bespoke editor-group drag model + drop-apply logic with the quadraui controller, deleting the per-backend drag wiring. This brings the feature in line with the platform-neutrality rule in CLAUDE.md — the current arrangement is pre-quadraui tech debt that predates TabGroupController.
Blocked on: JDonaghy/quadraui#349. Do not start until that has landed and ~/src/quadraui is pulled.
Current state (what vimcode owns today)
VimCode implements the entire draggable-editor-group feature itself and reuses quadraui only for the geometry hit-test (quadraui::compute_drop_zone, called once at src/render.rs:12563). The rest is vimcode-side:
| Concern |
Location |
Recursive split-tree model — GroupLayout (Leaf/Split), GroupId, DropZone, GroupDivider |
src/core/window.rs:260–311 |
Tree mutation — split_at, remove, dividers, calculate_group_rects, ratio math |
src/core/window.rs:313–669 |
Drag state + drop-apply — tab_drag_begin, tab_drag_drop, move_tab_to_target_group(_at), move_tab_to_new_split, reorder_tab_in_group, close_group_by_id |
src/core/engine/windows.rs:2040–2224 |
Drop-zone adapter (vimcode bounds → quadraui::DropGroupRect, result → DropZone) |
src/render.rs:12441–12584 (build_tab_drop_groups, compute_tab_drop_zone) |
| Overlay geometry (highlight / insertion bar / ghost rects) |
src/render.rs:12586–12655 (compute_tab_drop_overlay) |
| Per-backend drag wiring — GTK ~74 lines |
src/gtk/mod.rs:7140–7410, 7545–7551 |
| Per-backend drag wiring — TUI ~38 lines |
src/tui_main/mouse.rs:874–906, 1086–1092 |
Goal
Migrate onto quadraui::TabGroupController (post-#349) so that:
- The recursive split model + drop mutations are deleted from vimcode and provided by quadraui.
- Per-backend GTK/TUI drag wiring collapses to thin event→controller forwarding (press/move/release →
begin_tab_drag / tab_drag_over / end_tab_drag).
- The vimcode adapters in
render.rs (build_tab_drop_groups, compute_tab_drop_zone, compute_tab_drop_overlay) are removed — the controller computes zones and draws its own overlay.
Work
- Adopt
TabGroupController as the editor-group backing store (replacing editor_groups / group_layout / active_group in Engine, or wrapping it).
- Map vimcode's tab content (windows/buffers) onto
PaneTab { content: Box<dyn BackendWidget> }.
- Forward backend mouse events to the controller's tab-drag lifecycle; delete
move_tab_to_*, reorder_tab_in_group, and the DropZone adapter once parity is confirmed.
- Remove
GroupLayout/DropZone from src/core/window.rs only if nothing else depends on them (window splits inside a group still use WindowLayout — keep that).
Seams that MUST keep working (do not regress)
- Session persistence —
SessionGroupLayout serde tree + flat back-compat fields (open_files_group1, active_group, group_split_direction/ratio) in src/core/engine/buffers.rs:3437–3537. Either keep serializing from the controller's tree or migrate the format with back-compat.
- Keyboard splits / focus —
Ctrl+\ split right, Ctrl+1–Ctrl+9 focus by tree position, Ctrl-W e/E, Alt+,/Alt+. resize (TUI), divider drag (GTK), and the user-configurable panel_keys.split_editor_right/down. These must map onto controller operations.
- Per-group tab bars and group dividers rendering across both backends.
Acceptance criteria
Why
Per CLAUDE.md platform-neutrality rule: drag/layout/click logic must live in quadraui or shared render.rs, never as per-backend code. This feature currently violates that with ~112 lines of GTK+TUI-specific drag wiring and a full second copy of the split-tree model. Completing quadraui#349 and migrating here removes the duplication and makes the capability reusable by every quadraui app.
Summary
Once
quadraui#349lands (cross-group tab drag-and-drop inTabGroupController), replace vimcode's bespoke editor-group drag model + drop-apply logic with the quadraui controller, deleting the per-backend drag wiring. This brings the feature in line with the platform-neutrality rule inCLAUDE.md— the current arrangement is pre-quadraui tech debt that predatesTabGroupController.Blocked on: JDonaghy/quadraui#349. Do not start until that has landed and
~/src/quadrauiis pulled.Current state (what vimcode owns today)
VimCode implements the entire draggable-editor-group feature itself and reuses quadraui only for the geometry hit-test (
quadraui::compute_drop_zone, called once atsrc/render.rs:12563). The rest is vimcode-side:GroupLayout(Leaf/Split),GroupId,DropZone,GroupDividersrc/core/window.rs:260–311split_at,remove,dividers,calculate_group_rects, ratio mathsrc/core/window.rs:313–669tab_drag_begin,tab_drag_drop,move_tab_to_target_group(_at),move_tab_to_new_split,reorder_tab_in_group,close_group_by_idsrc/core/engine/windows.rs:2040–2224quadraui::DropGroupRect, result →DropZone)src/render.rs:12441–12584(build_tab_drop_groups,compute_tab_drop_zone)src/render.rs:12586–12655(compute_tab_drop_overlay)src/gtk/mod.rs:7140–7410, 7545–7551src/tui_main/mouse.rs:874–906, 1086–1092Goal
Migrate onto
quadraui::TabGroupController(post-#349) so that:begin_tab_drag/tab_drag_over/end_tab_drag).render.rs(build_tab_drop_groups,compute_tab_drop_zone,compute_tab_drop_overlay) are removed — the controller computes zones and draws its own overlay.Work
TabGroupControlleras the editor-group backing store (replacingeditor_groups/group_layout/active_groupinEngine, or wrapping it).PaneTab { content: Box<dyn BackendWidget> }.move_tab_to_*,reorder_tab_in_group, and theDropZoneadapter once parity is confirmed.GroupLayout/DropZonefromsrc/core/window.rsonly if nothing else depends on them (window splits inside a group still useWindowLayout— keep that).Seams that MUST keep working (do not regress)
SessionGroupLayoutserde tree + flat back-compat fields (open_files_group1,active_group,group_split_direction/ratio) insrc/core/engine/buffers.rs:3437–3537. Either keep serializing from the controller's tree or migrate the format with back-compat.Ctrl+\split right,Ctrl+1–Ctrl+9focus by tree position,Ctrl-W e/E, Alt+,/Alt+. resize (TUI), divider drag (GTK), and the user-configurablepanel_keys.split_editor_right/down. These must map onto controller operations.Acceptance criteria
quadraui#349has landed and~/src/quadrauipulled (cd ~/src/quadraui && git pull).move_tab_to_*/ drop-zone adapters are gone;git diff --statshows the backend files shrinking.cargo test --no-default-features,cargo clippy -- -D warnings,cargo fmtall pass.Why
Per
CLAUDE.mdplatform-neutrality rule: drag/layout/click logic must live in quadraui or sharedrender.rs, never as per-backend code. This feature currently violates that with ~112 lines of GTK+TUI-specific drag wiring and a full second copy of the split-tree model. Completingquadraui#349and migrating here removes the duplication and makes the capability reusable by every quadraui app.