From ab8d634f8e8a1f1d45d91f19942efb41bb93ab2e Mon Sep 17 00:00:00 2001 From: Alastair <66482739+alastairsounds@users.noreply.github.com> Date: Thu, 18 Jun 2026 19:30:52 -0600 Subject: [PATCH] fix: split graceful vs passive stop in terminal stream (#4055) Co-authored-by: Alastair Scheuermann Co-authored-by: sxyazi --- yazi-term/src/source/unix.rs | 2 +- yazi-term/src/source/windows.rs | 2 +- yazi-term/src/stream/stream.rs | 2 ++ yazi-tui/src/raterm.rs | 20 +++++++++++++------- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/yazi-term/src/source/unix.rs b/yazi-term/src/source/unix.rs index eb341ab4..7e7f94a3 100644 --- a/yazi-term/src/source/unix.rs +++ b/yazi-term/src/source/unix.rs @@ -49,7 +49,7 @@ impl<'a> EventSource<'a> { // Stop waiting for events. if wakeup_ready { 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. diff --git a/yazi-term/src/source/windows.rs b/yazi-term/src/source/windows.rs index a0cc3bde..072546a5 100644 --- a/yazi-term/src/source/windows.rs +++ b/yazi-term/src/source/windows.rs @@ -28,7 +28,7 @@ impl<'a> EventSource<'a> { // More input is ready. WAIT_OBJECT_0 => Ok(()), // 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. WAIT_TIMEOUT => Err(io::Error::from(io::ErrorKind::TimedOut)), // An error occurred. diff --git a/yazi-term/src/stream/stream.rs b/yazi-term/src/stream/stream.rs index 69f699a7..ad83a29e 100644 --- a/yazi-term/src/stream/stream.rs +++ b/yazi-term/src/stream/stream.rs @@ -33,6 +33,8 @@ impl EventStream { } // try_poll() already handles Interrupted, this is defensive. 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) => { tx.send(Err(e)).ok(); break; diff --git a/yazi-tui/src/raterm.rs b/yazi-tui/src/raterm.rs index c50cc013..24b8a259 100644 --- a/yazi-tui/src/raterm.rs +++ b/yazi-tui/src/raterm.rs @@ -97,16 +97,22 @@ impl Raterm { let mut rx = self.stream.take().unwrap(); tokio::spawn(async move { - while let Some(Ok(event)) = rx.recv().await { - match event { - Event::Key(key) if key.kind != KeyEventKind::Press => continue, - Event::Mouse(mouse) if !YAZI.mgr.mouse_events.get().contains(mouse.kind.into()) => { - continue; + loop { + match rx.recv().await { + Some(Ok(event)) => match event { + Event::Key(key) if key.kind != KeyEventKind::Press => 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()); }); }