diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-08-03 02:05:27 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-03 02:05:27 +0300 |
| commit | 10eb0bc744165ae91dfce9fd731fe170410b34ec (patch) | |
| tree | 8622d429d9453c2e8d06630322804a702973d94a /src/pty/actor.rs | |
| parent | cbc31d34a1fb3da64415737de57ad10fe6af5ba5 (diff) | |
fix: propagate host color scheme to pane apps (#2214)
refs #714
Diffstat (limited to 'src/pty/actor.rs')
| -rw-r--r-- | src/pty/actor.rs | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/src/pty/actor.rs b/src/pty/actor.rs index 8c3a6b52..6fde5051 100644 --- a/src/pty/actor.rs +++ b/src/pty/actor.rs @@ -52,6 +52,8 @@ mod windows { pub(crate) struct PtyIoActorHandle { data_tx: mpsc::Sender<Bytes>, control_tx: std_mpsc::Sender<PtyIoControlCommand>, + write_tx: std_mpsc::Sender<Bytes>, + response_order: Arc<Mutex<()>>, accepting: Arc<Mutex<bool>>, } @@ -84,6 +86,16 @@ mod windows { self.data_tx.try_send(bytes) } + pub(crate) fn write_terminal_response(&self, response: impl FnOnce() -> Option<Bytes>) { + let _order = self + .response_order + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()); + if let Some(bytes) = response().filter(|bytes| !bytes.is_empty()) { + let _ = self.write_tx.send(bytes); + } + } + pub(crate) fn resize( &self, rows: u16, @@ -128,39 +140,55 @@ mod windows { let mut reader = master .try_clone_reader() .map_err(|err| std::io::Error::other(err.to_string()))?; - let writer = master + let mut writer = master .take_writer() .map_err(|err| std::io::Error::other(err.to_string()))?; - let writer = Arc::new(Mutex::new(writer)); let (data_tx, mut data_rx) = mpsc::channel::<Bytes>(1024); let (control_tx, control_rx) = std_mpsc::channel::<PtyIoControlCommand>(); + let (write_tx, write_rx) = std_mpsc::channel::<Bytes>(); + let response_order = Arc::new(Mutex::new(())); let accepting = Arc::new(Mutex::new(!initially_quiesced)); + std::thread::spawn(move || { + for bytes in write_rx { + if writer.write_all(&bytes).is_err() || writer.flush().is_err() { + break; + } + } + debug!(pane_id, "windows pty writer thread exiting"); + }); + { - let writer = Arc::clone(&writer); + let write_tx = write_tx.clone(); std::thread::spawn(move || { while let Some(bytes) = data_rx.blocking_recv() { - if write_all_locked(&writer, &bytes).is_err() { + if write_tx.send(bytes).is_err() { break; } } - debug!(pane_id, "windows pty writer thread exiting"); + debug!(pane_id, "windows pty input thread exiting"); }); } { - let writer = Arc::clone(&writer); + let write_tx = write_tx.clone(); + let response_order = Arc::clone(&response_order); std::thread::spawn(move || { let mut buf = [0u8; 8192]; loop { match reader.read(&mut buf) { Ok(0) => break, Ok(n) => { + let _order = response_order + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()); let result = on_read(&buf[..n]); - for response in result.terminal_responses { - if write_all_locked(&writer, &response).is_err() { - break; - } + if result + .terminal_responses + .into_iter() + .any(|response| write_tx.send(response).is_err()) + { + break; } } Err(err) => { @@ -177,7 +205,7 @@ mod windows { } { - let writer = Arc::clone(&writer); + let write_tx = write_tx.clone(); std::thread::spawn(move || { for command in control_rx { match command { @@ -191,10 +219,12 @@ mod windows { }) { warn!(pane_id, err = %err, "windows pty resize failed"); } - for response in request.terminal_responses { - if write_all_locked(&writer, &response).is_err() { - break; - } + if request + .terminal_responses + .into_iter() + .any(|response| write_tx.send(response).is_err()) + { + break; } } PtyIoControlCommand::Shutdown => break, @@ -207,22 +237,13 @@ mod windows { Ok(PtyIoActorHandle { data_tx, control_tx, + write_tx, + response_order, accepting, }) } } - fn write_all_locked( - writer: &Arc<Mutex<Box<dyn Write + Send>>>, - bytes: &[u8], - ) -> std::io::Result<()> { - let mut writer = writer - .lock() - .unwrap_or_else(|poisoned| poisoned.into_inner()); - writer.write_all(bytes)?; - writer.flush() - } - #[allow(dead_code)] fn _assert_duration_send(_: Duration) {} } |
