Skip to content

fix: adapt selector layout after terminal resize - #195

Merged
jdx merged 5 commits into
mainfrom
agent/adapt-layout-after-resize
Jul 26, 2026
Merged

fix: adapt selector layout after terminal resize#195
jdx merged 5 commits into
mainfrom
agent/adapt-layout-after-resize

Conversation

@jdx

@jdx jdx commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • retain each selector's previous rendered frame instead of only its original physical height
  • recalculate that frame's wrapped height using the terminal's current width before clearing it
  • refresh page capacity from the current terminal height on every redraw
  • clamp pages, cursors, and list scroll positions when the resized viewport no longer contains them
  • add focused capacity and navigation-clamping tests for Select and MultiSelect

Root cause

The wrapped-row fix in #192 recorded how many physical rows a frame occupied when it was drawn. After a terminal resize, that number could become stale because the terminal reflows the same text at a different width. Selector capacity was also calculated only at construction, so pagination continued using the original terminal height.

Behavior

Select, MultiSelect, and List now retain the previous frame text. On the next redraw after a resize, they measure that old frame at the new width, erase the reflowed footprint, recalculate capacity from the new height, clamp navigation state, and render the corrected layout.

This intentionally updates on the next input/redraw. Immediate idle redraw would require a resize-aware input event API; console::Term::read_key currently blocks on key input and does not expose resize events.

The branch is rebased onto the merged #193, so resize correction is enclosed in the synchronized-output update: geometry is recalculated correctly and the clear/redraw transition is presented atomically.

Validation

  • cargo fmt --check
  • cargo test --lib --tests (45 unit tests and 16 integration tests passed)
  • cargo clippy --all-targets -- -D warnings

This PR was generated by an AI coding assistant.


Note

Medium Risk
Unix-only low-level TTY/signal/select code affects all three interactive prompts; non-Unix still uses blocking read_key only, but incorrect raw-mode or signal handling could break input or leave the terminal in a bad state.

Overview
Terminal resize handling for Select, MultiSelect, and List on Unix: prompts now react when the window changes size, not only on the next keypress.

Adds EventReader (src/event.rs) that multiplexes keyboard input with SIGWINCH via select, raw TTY mode, and a signal-hook pipe. Resize events surface as read_key returning None, which triggers a full-screen clear and redraw on the next loop.

Layout and erase fixes: widgets keep the previous frame text (last_frame) instead of a fixed row count. Before clearing, wrapped height is recomputed at the current terminal width; each redraw calls refresh_layout to derive page capacity from terminal height and clamp page, cursor, and list scroll so the focused / first-visible item stays stable. Select paging now counts filtered options.

Tests: unit tests for resize_layout, plus a PTY integration test (tests/resize.rs) asserting an idle prompt emits a second synchronized frame after resize without keyboard input. libc (unix) and portable-pty (dev) dependencies added.

Reviewed by Cursor Bugbot for commit 1f712ca. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jdx, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: dcf052f9-452f-400c-b6e3-6058ec863516

📥 Commits

Reviewing files that changed from the base of the PR and between a5facf0 and 1f712ca.

📒 Files selected for processing (7)
  • Cargo.toml
  • src/event.rs
  • src/lib.rs
  • src/list.rs
  • src/multiselect.rs
  • src/select.rs
  • tests/resize.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jdx
jdx force-pushed the agent/adapt-layout-after-resize branch from c699c24 to fffd733 Compare July 26, 2026 18:42
Comment thread src/list.rs Outdated
@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown

Greptile Summary

The PR makes selector layouts resize-aware.

  • Preserves the absolute focused option or visible list offset when terminal capacity changes.
  • Recalculates frame geometry and page capacity before redraw.
  • Adds Unix resize-event handling and focused resize regression tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported selector focus and list-offset resize issues are corrected by preserving their absolute positions before recalculating pagination.

Important Files Changed

Filename Overview
src/event.rs Adds Unix SIGWINCH and terminal-input multiplexing so active prompts redraw immediately after resize.
src/select.rs Preserves the selected option’s absolute filtered index while remapping pagination to the resized capacity.
src/multiselect.rs Preserves the focused option across capacity changes and redraws from retained frame content.
src/list.rs Preserves the first visible entry by converting the old combined offset into the resized page and scroll state.
tests/resize.rs Adds PTY coverage demonstrating that a resize triggers another synchronized redraw.
Cargo.toml Adds the Unix-only libc dependency required by terminal event handling.

Reviews (6): Last reviewed commit: "fix: reset selector viewport after resiz..." | Re-trigger Greptile

Comment thread src/select.rs Outdated
Comment thread src/list.rs Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cd236c4. Configure here.

Comment thread src/event.rs
@jdx
jdx merged commit 03b60eb into main Jul 26, 2026
8 checks passed
@jdx
jdx deleted the agent/adapt-layout-after-resize branch July 26, 2026 20:19
@jdx jdx mentioned this pull request Jul 26, 2026
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.

1 participant