fix: split graceful vs passive stop in terminal stream (#4055)

Co-authored-by: Alastair Scheuermann <alastairsounds@users.noreply.github.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
Alastair 2026-06-18 19:30:52 -06:00 committed by GitHub
parent 85132ff343
commit ab8d634f8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 17 additions and 9 deletions

View file

@ -49,7 +49,7 @@ impl<'a> EventSource<'a> {
// Stop waiting for events. // Stop waiting for events.
if wakeup_ready { if wakeup_ready {
while read_complete(&*self.waker, &mut [0u8; 1024])? != 0 {} while read_complete(&*self.waker, &mut [0u8; 1024])? != 0 {}
return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); return Err(io::Error::from(io::ErrorKind::ConnectionAborted));
} }
// More input is ready. // More input is ready.

View file

@ -28,7 +28,7 @@ impl<'a> EventSource<'a> {
// More input is ready. // More input is ready.
WAIT_OBJECT_0 => Ok(()), WAIT_OBJECT_0 => Ok(()),
// Stop waiting for events. // Stop waiting for events.
r if r == WAIT_OBJECT_0 + 1 => Err(io::Error::from(io::ErrorKind::UnexpectedEof)), r if r == WAIT_OBJECT_0 + 1 => Err(io::Error::from(io::ErrorKind::ConnectionAborted)),
// Timeout expired. // Timeout expired.
WAIT_TIMEOUT => Err(io::Error::from(io::ErrorKind::TimedOut)), WAIT_TIMEOUT => Err(io::Error::from(io::ErrorKind::TimedOut)),
// An error occurred. // An error occurred.

View file

@ -33,6 +33,8 @@ impl EventStream {
} }
// try_poll() already handles Interrupted, this is defensive. // try_poll() already handles Interrupted, this is defensive.
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue, Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
// event source was gracefully stopped, stop the stream as well.
Err(e) if e.kind() == io::ErrorKind::ConnectionAborted => break,
Err(e) => { Err(e) => {
tx.send(Err(e)).ok(); tx.send(Err(e)).ok();
break; break;

View file

@ -97,16 +97,22 @@ impl Raterm {
let mut rx = self.stream.take().unwrap(); let mut rx = self.stream.take().unwrap();
tokio::spawn(async move { tokio::spawn(async move {
while let Some(Ok(event)) = rx.recv().await { loop {
match event { match rx.recv().await {
Event::Key(key) if key.kind != KeyEventKind::Press => continue, Some(Ok(event)) => match event {
Event::Mouse(mouse) if !YAZI.mgr.mouse_events.get().contains(mouse.kind.into()) => { Event::Key(key) if key.kind != KeyEventKind::Press => continue,
continue; Event::Mouse(mouse) if !YAZI.mgr.mouse_events.get().contains(mouse.kind.into()) => {
continue;
}
_ => yazi_shared::event::Event::Term(event).emit(),
},
Some(Err(_)) => {
AppProxy::quit(Default::default());
break;
} }
_ => yazi_shared::event::Event::Term(event).emit(), None => break,
} }
} }
AppProxy::quit(Default::default());
}); });
} }