#582: Split-pane divider drag is broken in both TUI and GTK (falls through to text-selection) - #584
Merged
JDonaghy merged 3 commits intoJul 16, 2026
Conversation
Root cause: WindowLayout (vim window splits, one tree per Tab) had no
divider concept at all — no dividers(), no ratio-adjustment methods —
unlike GroupLayout (the separate editor-group-split feature), which
already had full working divider support. Dragging a :vsplit boundary
had no hit region to grab, so the click fell through to text-selection.
- core/window.rs: mirror GroupLayout's dividers()/set_ratio_at_index()/
adjust_ratio_at_index()/parent_split_of() onto WindowLayout; add
WindowDivider (a GroupDivider tagged with its owning GroupId, since
each group's WindowLayout numbers splits independently).
- core/engine/windows.rs: Engine::calculate_window_dividers(); rewire
the dead Ctrl-W +/-/</>/=/_/| resize commands (previously only ever
touched group_layout, a no-op for window splits) to try the active
window's split first, falling back to the editor-group split — this
preserves the existing group-split behavior locked in by
tests/vim_compat_batch.rs while fixing window splits.
- render.rs: shared divider_hit_test/divider_ratio_from_pos helpers
(generic over a new DividerGeometry trait), used by both the new
window-divider paths AND refactored into the pre-existing group-
divider code in both backends, removing duplicated hit-test/drag math
instead of adding a third copy.
- gtk/mod.rs, tui_main/{mod,mouse}.rs: thin per-backend wiring (hit-test
+ drag-state + drag-update + reset-on-mouse-up) mirroring the existing
group-divider call sites.
- tests/wincmd.rs: new assertions that Ctrl-W resize/equalize/maximize
actually move a real :vsplit's ratio (the pre-existing tests only
checked window count, never the ratio).
No quadraui primitive covers this (checked primitives/split.rs — a
two-pane primitive, not an N-way tree); flagged as a follow-up quadraui
issue rather than blocking this fix.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…plit line Smoke test failed 3 of 4 combos after the initial #582 fix: - TUI :split (horizontal) — completely unclickable. `render_separators` draws nothing there by design (the upper window's own status line, at `position - 1`, already marks the boundary when `window_status_line` is on, the default) but the hit-test only accepted `position` exactly — one row below the only thing the user can see and click. - TUI :vsplit (vertical) — ~50% flaky for the same reason: the visible separator/scrollbar glyph `render_separators` draws sits at `position - 1`, but the hit-test only accepted `position`. - GTK :vsplit — nothing rendered at all; GTK never painted a window- divider line for either axis, unlike the horizontal case which is incidentally marked by the per-window status bar. Fixes: - tui_main/mouse.rs: widen the window-divider hit-test tolerance from `(0.0, 1.0)` to `(1.0, 1.0)` on both axes so both the visible glyph (`position - 1`) and the boundary cell (`position`) register. Updated the existing `:vsplit` test's "one column off must miss" case (it encoded the very off-by-one this fixes) and added a `:split` test for the previously-untested horizontal axis. - render.rs: added `divider_to_split()`, converting a `DividerGeometry` divider into the `(quadraui::Split, quadraui::Rect)` pair backends need for `backend.draw_split()` — quadraui's existing divider-line primitive (already wired for both backends via `Surface::Split`), unused by the original #582 fix. Each divider is always a 2-pane boundary regardless of `WindowLayout` being an N-way tree, so the primitive applies per-divider without needing an N-way variant. - gtk/mod.rs: paint window dividers via `divider_to_split` for the vertical (`:vsplit`) axis only — horizontal is left alone since the per-window status bar there already works and matches what the TUI fix aligns its hit-test to. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Iteration-2 smoke: GTK `:vsplit` still had no visible divider and its drag still fell through to text-selection, despite 546a212 adding `divider_to_split()` specifically to paint that line. Root cause is not the paint call — it was wired correctly and does run. Both the paint and the hit-test were individually "right", in two different coordinate frames: - `render_content` anchors `editor_bounds` at `AppShellLayout:: main_content_bounds` — an ABSOLUTE rect, origin offset right by the activity bar (~48px) + sidebar and down by the title-bar band (#550 moved window rects to this convention). - Every divider hit-test/drag handler rebuilt its own `content_bounds` at `(0.0, 0.0)`, with a different height formula (`gtk_editor_bottom`) than the renderer's `editor_area_h`. Clicks arrive in absolute DA coords (single-DA architecture, #217), so the hit band sat one activity-bar-width left of the painted line. The `:vsplit` band was therefore unreachable and the press fell through to text-selection. `:split` only *appeared* to work because its y-error is small: a click on the per-window status bar landed inside the 6px band by luck, which is what the iteration-1 note misread as "the status bar already marks the boundary". Fixes: - gtk/mod.rs: cache the exact `(editor_bounds, tab_bar_h)` each `render_content` pass painted with, and hit-test/drag against it via `painted_editor_bounds()`. Makes hit-test-agrees-with-paint true by construction rather than by two formulas being hand-synced. Applied to all four sites — window-divider AND editor-group-divider, press AND drag-motion — since the group path carried the identical latent bug. - gtk/mod.rs: paint window dividers on BOTH axes, dropping the `Vertical`-only filter. `:split`'s status-bar "handle" is a coincidence of an unrelated feature, not a divider; a real line makes what is grabbable match what is drawn. - render.rs: regression tests pinning the invariant the fix rests on — a divider's hit band and its painted rect both track `axis_start`, so an origin-shifted recomputation is NOT interchangeable with the painted one. Verified non-vacuous by re-injecting the origin bug. Co-Authored-By: Claude Opus 4.8 <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.
Closes #582
Automated merge from the coordinator for assignment 899bfb2a85ff on issue #582.
Worker branch:
issue-582-split-pane-divider-drag-is-broken-in-bot→develop.