fix: drain delayed tmux terminal replies before events

This commit is contained in:
ZM.TreeWSL 2026-05-24 15:10:51 +02:00
parent d9cd1907d9
commit 6e7a34fbd2
2 changed files with 38 additions and 2 deletions

View file

@ -58,4 +58,32 @@ impl Tty {
let result = read();
(buf, result)
}
pub fn drain_until_quiet(&self, timeout: Duration, quiet: Duration) -> std::io::Result<usize> {
let mut drained = 0;
let until = Instant::now() + timeout;
let mut stdin = self.stdin.lock();
while Instant::now() < until {
match stdin.poll(quiet) {
Ok(true) => {}
Ok(false) => break,
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
let mut b = [0u8];
loop {
match stdin.read_exact(&mut b) {
Ok(()) => {
drained += 1;
break;
}
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
}
}
Ok(drained)
}
}

View file

@ -1,4 +1,4 @@
use std::{io::{self, Write}, ops::Deref};
use std::{io::{self, Write}, ops::Deref, time::Duration};
use anyhow::Result;
use ratatui::{CompletedFrame, Frame, Terminal, buffer::Buffer, layout::Rect};
@ -63,7 +63,15 @@ impl Raterm {
let mut term = Self {
inner: Terminal::new(RatermBackend::new(TTY.writer()))?,
stream: EventStream::from(&*TERM),
stream: {
if TMUX.get() {
// tmux passthrough can deliver terminal query replies out of order.
// Keep them out of EventStream, where DCS/CSI payload bytes
// such as `r`, `f`, or `z` are indistinguishable from keys.
let _ = TTY.drain_until_quiet(Duration::from_millis(1000), Duration::from_millis(100));
}
EventStream::from(&*TERM)
},
last_area: Default::default(),
last_buffer: Default::default(),
};