fix(tui): login picker scrolls in a capped viewport; the moon never clips

Root cause (issues: unscrollable list + half-blocked moon): the stacked
welcome layout gave the menu one Length row per item. With ~30 advertised
providers the vertical layout overflowed and the constraint solver
squeezed every Length — clipping the logo — while rows past the fold were
silently unreachable.

- WelcomeLayout::compute_inner caps the menu to the rows genuinely left
  over after logo/prompt/version, so the chrome never gets squeezed.
- render_menu is now a minimal-scroll viewport: it scrolls only when the
  selection exits it (stable under hover — no re-centering feedback
  loop), draws the picker-style scrollbar, and returns index-aligned hit
  rects (zero Rect for off-screen rows) plus the offset, which AppView
  feeds back next frame.
- Mouse wheel moves the login-picker selection (clamped, not wrapping).

Test: pending_menu_scrolls_and_never_clips_the_moon renders the full
method list at 40 rows and asserts the whole moon (10 braille rows), the
version badge, and that selecting Quit scrolls it into view.

Verified: kigi-tui 6864 tests green, clippy clean.
This commit is contained in:
ZacharyZhang-NY committed 2026-07-22 15:31:18 -04:00
1 parent 48d89c7830
commit c2d1067f0d
5 files changed
+175 -14

No files matched your search

@@ -140,6 +140,7 @@ fn test_app() -> AppView {
welcome_prompt_focused: false,
welcome_tip_typing_dismissed: false,
welcome_menu_index: None,
welcome_menu_scroll: 0,
welcome_menu_rects: Vec::new(),
welcome_import_banner_rect: None,
last_mouse_pos: None,