Skip to content

#756: Converge the mouse ladder slice 6: delete handle_mouse's remains and GTK's handle_mouse_*_msg - #773

Merged
JDonaghy merged 2 commits into
developfrom
issue-756-converge-the-mouse-ladder-slice-6-delete
Sep 2, 2026
Merged

#756: Converge the mouse ladder slice 6: delete handle_mouse's remains and GTK's handle_mouse_*_msg#773
JDonaghy merged 2 commits into
developfrom
issue-756-converge-the-mouse-ladder-slice-6-delete

Conversation

@JDonaghy

@JDonaghy JDonaghy commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Closes #756

Automated PR opened by coordinator for review of issue #756.

Slice 6 of the #733 mouse ladder. Both backends carried a complete,
independently-ordered copy of the "pointer moved with the left button
held" ladder — `MouseEventKind::Drag(Left)` in `src/tui_main/mouse.rs`
and `App::handle_mouse_drag_msg` in `src/gtk/mod.rs` — and they had
drifted three ways:

1. TUI had no minimap drag arm at all. Its arm matched `Down | Drag` but
   sat below a `Down`-only gate, so press-and-hold on a TUI minimap
   seeked once and froze. GTK's has worked since #35.
2. The armed-scrollbar widget-id tables were two disjoint half-tables:
   each backend's switch was missing every id the other had, and the
   three shared ids were written out twice.
3. The two orders disagreed on which gesture wins.

`render::route_mouse_drag` + `MouseDragState`/`MouseDragRoute` state the
order ONCE; `render::apply_scroll_offset` is the union of the two
widget-id tables; `render::apply_terminal_content_drag` and
`render::in_terminal_pane_content` resolve terminal drags through the
same `route_bottom_panel_click` the press path already used (GTK's drag
path still did a bare `x / char_width` against a window-absolute x — bug
2 of the #754 banner, fixed on the press side and left here).

Both bespoke ladders are deleted in this commit. What stays per backend
is stated at each call site: the terminal resize/split clamps (unit
conversions), GTK's Pango column inverse, and the absent GTK sidebar
separator / command-line selection / explorer DnD.

Tests, all verified RED against the unfixed tree:
- `both_backends_resolve_the_same_layout_and_point_to_the_same_rung` —
  one engine painted twice (TUI cells, GTK pixels), same logical points
  through both conventions, same rung. RED when the router's editor-zone
  hit test is hardcoded to the TUI's cell metrics.
- `armed_gestures_resolve_in_a_fixed_order` pins the ladder itself.
- `tui_minimap_drag_keeps_seeking_while_the_button_is_held` (TuiDriver,
  asserts on painted `line N content` markers) — RED without the new
  `MouseDragRoute::Minimap` arm.
- `an_editor_text_drag_paints_a_selection_through_the_shared_drag_router`
  (GtkDriver, asserts on probed pixels) — RED with the `EditorText` arm
  disabled.

Entry-point line count: 3,874 -> 3,710 (measured at pickup on this
branch; 4,861 when #756 was filed). The <800 target is NOT met — see the
PR body.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking regression: `armed_target: drag_state.is_active()` made every
TUI editor text-selection drag resolve to `MouseDragRoute::ArmedTarget`
instead of `EditorText`, because the same click path arms the shared
`quadraui::DragState` with `DragTarget::TextSelection` (#565) — not just
scrollbars/picker thumbs, which is what `ArmedTarget`'s handler
(`apply_scrollbar_drag`) actually reacts to. `EditorText`, the only arm
that calls `Engine::mouse_drag` to extend the selection, was unreachable
for the whole gesture. Fixed with a new shared
`render::drag_state_arms_scrollbar`, called from both backends, that
excludes `TextSelection` from `armed_target` — a no-op on GTK, which
never arms `TextSelection` on its shared `DragState`.

Added `tui_editor_text_drag_paints_a_selection_through_the_shared_drag_router`
(`src/tui_main/shell_app.rs`), the TUI twin of the GTK black-box test the
review noted was missing. Verified RED against the unfixed router.

Non-blocking concern also fixed: once `armed_target` no longer swallows
a TextSelection drag, the drag falls through to pure geometry again,
so a selection drag whose pointer strays over the minimap strip or into
the terminal panel could get hijacked mid-gesture. Added
`MouseDragState::text_selection_active` (driven by the pre-existing,
already-shared `Engine::mouse_drag_active`) as an armed rung ahead of
that geometry, plus a router-level regression test.

Not addressed: the <800-line entry-point target. Measured after this
fix: handle_mouse 2470, handle_mouse_event 368, handle_mouse_click_msg
430, handle_mouse_drag_msg 278, try_route_sidebar_mouse_event 174 = 3720
total (vs 3710 before this fix; the delta is doc comments on the two
touched call sites). Converging the remaining click/hover/scroll ladder
in `handle_mouse` (~1,200+ of its 2,470 lines are still bespoke Down /
Moved / right-click handling, not thin `render.rs` delegation) is a
multi-session-scale rewrite across both backends, not something this
fix iteration can responsibly attempt without either running out of
budget mid-rewrite or shipping it unverified. Flagging for the
coordinator per the review's own framing: either re-scope/re-title this
PR to the drag rung it actually converges and file a tracked follow-up
for the rest of the closing slice, or plan further fix iterations
specifically for that conversion.

cargo build, cargo clippy -- -D warnings, cargo fmt --check all clean.
Scoped test run (render::mouse_drag_router_tests, the new/existing TUI
shell_app drag tests, tui_main::mouse::tests, gtk::testing::*): 259/259
passing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@JDonaghy
JDonaghy merged commit 58a5cd9 into develop Sep 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Converge the mouse ladder slice 6: delete handle_mouse's remains and GTK's handle_mouse_*_msg

1 participant