Skip to content

fix: Apply SSH window-change requests so the session pty resizes mid-session - #968

Closed
gominimal-aw-bot[bot] wants to merge 1 commit into
mainfrom
inbox-patch/fix-window-change-resize-4dbdafae19d3186d
Closed

fix: Apply SSH window-change requests so the session pty resizes mid-session#968
gominimal-aw-bot[bot] wants to merge 1 commit into
mainfrom
inbox-patch/fix-window-change-resize-4dbdafae19d3186d

Conversation

@gominimal-aw-bot

@gominimal-aw-bot gominimal-aw-bot Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #965
Routing-Key: inbox-route/I_kwDOSUhdos8AAAABKH1lvg

The defect

minimald's attached-binding message loop in
crates/minimald/src/session_host.rs matched only ChannelMsg::RequestPty
and ChannelMsg::Data; every other channel message — including
ChannelMsg::WindowChange — fell into a _ => tracing::debug!("ignoring channel request ...") catch-all and was discarded. Because a taken SSH
channel delivers post-attach requests to the binding's own message stream
(the same route the existing RequestPty arm already relies on), a
client's window-change on every terminal resize was silently dropped.
The guest PTY therefore kept its attach-time rows/cols, no TIOCSWINSZ
ran, no SIGWINCH reached the foreground process group, and full-screen
TUI apps repainted against stale dimensions — the reported "jumbled"
redraw. (Detach/re-attach appeared to fix it because attach() re-sizes
the PTY and parser.)

A second, narrower gap: the russh Handler in
crates/minimald/src/connection.rs implemented pty_request but not
window_change_request, so a resize arriving before the shell attaches
(between pty-req and shell) was also lost.

The change

  • session_host.rs — add a ChannelMsg::WindowChange arm to the
    binding loop that forwards the new dimensions as
    Either::Right(RequestedPty { .. }) down stdin_tx, exactly like the
    initial pty-req. The existing consumer (set_size()
    set_winsize()) then runs TIOCSWINSZ on the master and re-sizes the
    vt100_ctt parser, so the kernel delivers SIGWINCH. window-change
    carries no term/modes, so those are left empty.
  • connection.rs — implement window_change_request on the
    Handler, updating the pending PTY size so the session opens at the
    latest dimensions. Once the shell attaches the channel is taken and the
    pending config is gone, so a None there is expected and ignored; the
    request never sets want_reply, so no channel reply is sent.
  • test_harness.rs / session.rs — a reusable open_shell_resized
    harness helper plus two regression tests. The mock launcher gains a
    size sentinel that runs stty size, letting a test observe the PTY
    geometry over the channel.

The debug-level catch-all for genuinely-noisy duplicate requests is left
as-is; once WindowChange is handled the remaining _ arm is only the
harmless pre-attach duplicates the existing comment describes.

I checked Distillery (scoped to project minimal) for prior art on this
path: it surfaced the session-host scaffolding (PR #375) and terminal-meta
tracking (PR #421), but no prior window-change handling — nothing
load-bearing to cite for the fix itself.

Verification

Gate run from the workspace root against target/Cargo.toml, all green:

  • cargo fmt --all --check — clean, no diff.
  • cargo clippy --workspace --locked -- -D warnings — finished, 0 warnings.
  • cargo build --workspace --lockedFinished dev profile (exit 0).
  • cargo test --workspace --locked — full suite passed (exit 0). The two
    new tests window_change_after_attach_resizes_the_pty and
    window_change_before_shell_sets_initial_pty_size report test result: ok. 2 passed; 0 failed (each asserts stty size inside the session
    reports the resized 40×120 geometry; both fail without the fix).

Generated by inbox-patch ·

Note

Fix SSH window_change requests to resize the PTY mid-session

  • Implements window_change_request in ConnectionHandler (connection.rs) to update PTY dimensions both before and after shell attach.
  • Extends the Binding.run loop in session_host.rs to forward WindowChange messages to the session host via stdin_tx, triggering a TIOCSWINSZ resize.
  • Adds integration tests covering mid-session resize and pre-attach resize setting the initial PTY size, using a mock shell that reports stty size output on demand.

Macroscope summarized c050b08.

Summary by CodeRabbit

  • Bug Fixes

    • Terminal resize events now update active sessions correctly.
    • Resizes received before shell startup are applied when the terminal is initialized.
    • Interactive SSH sessions now reflect updated terminal dimensions, including character and pixel sizes.
  • Tests

    • Added coverage for terminal resizing before and after shell attachment.

The attached-binding message loop in session_host.rs handled only
RequestPty and Data channel messages; every other message, including
WindowChange, fell into a debug-level catch-all and was dropped. SSH
window-change requests, which the client sends on each terminal resize,
were therefore ignored, so the guest pty kept its attach-time size and
TUI apps repainted at stale dimensions after a mid-session resize.

Add a ChannelMsg::WindowChange arm to the binding loop that forwards the
new dimensions down the same path as the initial pty-req, so the
existing set_size() runs TIOCSWINSZ on the master and re-sizes the vt100
parser (which makes the kernel deliver SIGWINCH to the process group).

Also implement window_change_request on the russh Handler for resizes
that arrive before the shell attaches, updating the pending pty size so
the session opens at the latest dimensions.

Add regression tests covering both the mid-session and pre-attach resize
paths, asserting stty size inside the session reflects the new geometry.
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

SSH window-change messages now update pending PTY dimensions before shell attachment and forward resize events to attached session hosts. Test helpers and regression tests verify both pre-attach and mid-session terminal resizing.

Changes

Terminal resize handling

Layer / File(s) Summary
Pending PTY resize handling
crates/minimald/src/connection.rs, crates/minimald/src/test_harness.rs
The SSH handler stores pre-attach character and pixel dimensions, while the test client can send an initial PTY request followed by a pre-attach resize.
Attached PTY resize forwarding
crates/minimald/src/session_host.rs
Attached bindings forward WindowChange dimensions through the existing PTY update path; the mock shell reports its current stty size.
Resize regression coverage
crates/minimald/src/session.rs
Tests query terminal dimensions and verify resizing after shell attachment and before shell attachment.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: twitchyliquid64

Sequence Diagram(s)

sequenceDiagram
  participant SSHClient
  participant ConnectionHandler
  participant Binding
  participant PTY
  SSHClient->>ConnectionHandler: send window-change
  ConnectionHandler->>Binding: deliver resize event
  Binding->>PTY: forward updated dimensions
  PTY-->>SSHClient: terminal reflects new size
Loading

Poem

A rabbit hops where terminals gleam,
Resizing rows in a pixel-bright stream.
Before shells wake or sessions begin,
New window sizes are carried in.
“Hop hop!” says the PTY, “let redraws win!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements the resize handling and regression tests requested in [#965].
Out of Scope Changes check ✅ Passed The changes stay focused on the resize fix, test harness, and regression coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is concise, conventional, and accurately summarizes the main fix: handling SSH window-change resizing mid-session.
Description check ✅ Passed The description covers the defect, the change, and verification with test output, though it does not follow the template headings exactly.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@norrietaylor
norrietaylor marked this pull request as ready for review July 25, 2026 06:14
@twitchyliquid64
twitchyliquid64 deleted the inbox-patch/fix-window-change-resize-4dbdafae19d3186d branch July 30, 2026 00:31
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.

diag: minimald's session host never applies SSH window-change requests: the attached-binding message loop in c

1 participant