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
Closed
Conversation
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.
📝 WalkthroughWalkthroughSSH ChangesTerminal resize handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 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
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
norrietaylor
marked this pull request as ready for review
July 25, 2026 06:14
twitchyliquid64
deleted the
inbox-patch/fix-window-change-resize-4dbdafae19d3186d
branch
July 30, 2026 00:31
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.
Fixes #965
Routing-Key: inbox-route/I_kwDOSUhdos8AAAABKH1lvg
The defect
minimald's attached-binding message loop incrates/minimald/src/session_host.rsmatched onlyChannelMsg::RequestPtyand
ChannelMsg::Data; every other channel message — includingChannelMsg::WindowChange— fell into a_ => tracing::debug!("ignoring channel request ...")catch-all and was discarded. Because a taken SSHchannel delivers post-attach requests to the binding's own message stream
(the same route the existing
RequestPtyarm already relies on), aclient's
window-changeon every terminal resize was silently dropped.The guest PTY therefore kept its attach-time rows/cols, no
TIOCSWINSZran, no
SIGWINCHreached the foreground process group, and full-screenTUI apps repainted against stale dimensions — the reported "jumbled"
redraw. (Detach/re-attach appeared to fix it because
attach()re-sizesthe PTY and parser.)
A second, narrower gap: the russh
Handlerincrates/minimald/src/connection.rsimplementedpty_requestbut notwindow_change_request, so a resize arriving before the shell attaches(between
pty-reqandshell) was also lost.The change
session_host.rs— add aChannelMsg::WindowChangearm to thebinding loop that forwards the new dimensions as
Either::Right(RequestedPty { .. })downstdin_tx, exactly like theinitial
pty-req. The existing consumer (set_size()→set_winsize()) then runsTIOCSWINSZon the master and re-sizes thevt100_cttparser, so the kernel deliversSIGWINCH.window-changecarries no term/modes, so those are left empty.
connection.rs— implementwindow_change_requeston theHandler, updating the pending PTY size so the session opens at thelatest dimensions. Once the shell attaches the channel is taken and the
pending config is gone, so a
Nonethere is expected and ignored; therequest never sets
want_reply, so no channel reply is sent.test_harness.rs/session.rs— a reusableopen_shell_resizedharness helper plus two regression tests. The mock launcher gains a
sizesentinel that runsstty size, letting a test observe the PTYgeometry over the channel.
The
debug-level catch-all for genuinely-noisy duplicate requests is leftas-is; once
WindowChangeis handled the remaining_arm is only theharmless pre-attach duplicates the existing comment describes.
I checked Distillery (scoped to project
minimal) for prior art on thispath: it surfaced the session-host scaffolding (PR #375) and terminal-meta
tracking (PR #421), but no prior
window-changehandling — nothingload-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 --locked—Finished dev profile(exit 0).cargo test --workspace --locked— full suite passed (exit 0). The twonew tests
window_change_after_attach_resizes_the_ptyandwindow_change_before_shell_sets_initial_pty_sizereporttest result: ok. 2 passed; 0 failed(each assertsstty sizeinside the sessionreports the resized 40×120 geometry; both fail without the fix).
Note
Fix SSH
window_changerequests to resize the PTY mid-sessionwindow_change_requestinConnectionHandler(connection.rs) to update PTY dimensions both before and after shell attach.Binding.runloop in session_host.rs to forwardWindowChangemessages to the session host viastdin_tx, triggering aTIOCSWINSZresize.stty sizeoutput on demand.Macroscope summarized c050b08.
Summary by CodeRabbit
Bug Fixes
Tests