Description
When typing quickly in a psmux pane, the cursor advances correctly but characters are not rendered on screen. Typing slowly works fine — each character appears as expected. This is a regression that did not exist before.
Steps to Reproduce
- Open a psmux session
- Type quickly in any shell (bash, pwsh, etc.)
- Observe that the cursor moves forward with each keystroke, but some or all characters behind the cursor fail to render
- Typing slowly renders every character correctly
Root Cause
Commit 694156e ("fix: bounded frame push prevents copy-mode scroll memory leak") replaced the unbounded mpsc::channel per client with a single-slot Arc<Mutex<Option<String>>>. The push_frame() function now overwrites any unconsumed frame in the slot:
// src/types.rs — push_frame()
slots.retain(|(_, slot)| {
// overwrites any pending frame — only "latest" is kept
*pending = Some(frame.to_string());
...
});
And the writer thread in connection.rs polls the slot on a 5ms timeout:
// 2. Check the frame slot — take the latest pushed frame
let frame = frame_lock.lock().ok().and_then(|mut slot| slot.take());
During fast typing:
- Each keystroke triggers a PTY update → server generates a new frame
- If multiple frames arrive within the 5ms polling window, intermediate frames are overwritten and never delivered to the client
- The client only receives the "latest" frame, which may have the correct cursor position but intermediate rendering states are lost
- The client-side skip logic (
dump_buf == prev_dump_buf) can further compound this if timing causes a stale comparison
The previous unbounded channel design queued all frames, guaranteeing each one was delivered and rendered. The single-slot design trades that guarantee for bounded memory — fixing the copy-mode scroll leak but breaking fast typing.
Expected Behavior
All typed characters should render on screen regardless of typing speed.
Suggested Fix
Consider a bounded channel (e.g., mpsc::sync_channel with a small capacity like 8-16) instead of a single-slot overwrite. This would:
- Still bound memory (unlike the original unbounded channel)
- Allow a small burst of frames to queue without being dropped
- Only drop frames under sustained high-throughput scenarios (like the scroll case the fix was targeting)
Alternatively, the frame slot could use a dirty flag + condvar to wake the writer thread immediately on each new frame rather than relying on the 5ms poll interval, reducing the window for overwrites.
Environment
- Windows 11
- psmux latest (post-694156e)
Description
When typing quickly in a psmux pane, the cursor advances correctly but characters are not rendered on screen. Typing slowly works fine — each character appears as expected. This is a regression that did not exist before.
Steps to Reproduce
Root Cause
Commit 694156e ("fix: bounded frame push prevents copy-mode scroll memory leak") replaced the unbounded
mpsc::channelper client with a single-slotArc<Mutex<Option<String>>>. Thepush_frame()function now overwrites any unconsumed frame in the slot:And the writer thread in
connection.rspolls the slot on a 5ms timeout:During fast typing:
dump_buf == prev_dump_buf) can further compound this if timing causes a stale comparisonThe previous unbounded channel design queued all frames, guaranteeing each one was delivered and rendered. The single-slot design trades that guarantee for bounded memory — fixing the copy-mode scroll leak but breaking fast typing.
Expected Behavior
All typed characters should render on screen regardless of typing speed.
Suggested Fix
Consider a bounded channel (e.g.,
mpsc::sync_channelwith a small capacity like 8-16) instead of a single-slot overwrite. This would:Alternatively, the frame slot could use a dirty flag + condvar to wake the writer thread immediately on each new frame rather than relying on the 5ms poll interval, reducing the window for overwrites.
Environment