diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/record.rs | 58 | ||||
-rw-r--r-- | src/cmd/stream.rs | 58 | ||||
-rw-r--r-- | src/cmd/watch.rs | 18 | ||||
-rw-r--r-- | src/error.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/resize.rs | 103 |
6 files changed, 74 insertions, 169 deletions
diff --git a/src/cmd/record.rs b/src/cmd/record.rs index 2d9116c..d25df4e 100644 --- a/src/cmd/record.rs +++ b/src/cmd/record.rs @@ -68,7 +68,8 @@ enum FileState { struct RecordSession { file: FileState, - process: crate::resize::ResizingProcess<crate::async_stdin::Stdin>, + process: + tokio_pty_process_stream::ResizingProcess<crate::async_stdin::Stdin>, stdout: tokio::io::Stdout, buffer: crate::term::Buffer, sent_local: usize, @@ -85,7 +86,7 @@ impl RecordSession { args: &[String], ) -> Self { let input = crate::async_stdin::Stdin::new(); - let process = crate::resize::ResizingProcess::new( + let process = tokio_pty_process_stream::ResizingProcess::new( tokio_pty_process_stream::Process::new(cmd, args, input), ); @@ -157,47 +158,40 @@ impl RecordSession { } fn poll_read_process(&mut self) -> component_future::Poll<(), Error> { - match component_future::try_ready!(self.process.poll()) { - Some(crate::resize::Event::Process(e)) => { - match e { - tokio_pty_process_stream::Event::CommandStart { - .. - } => { - if self.raw_screen.is_none() { - self.raw_screen = Some( - crossterm::RawScreen::into_raw_mode() - .context(crate::error::ToRawMode)?, - ); - } - } - tokio_pty_process_stream::Event::CommandExit { - .. - } => { - self.done = true; - } - tokio_pty_process_stream::Event::Output { data } => { - self.record_bytes(&data); - if let FileState::Open { writer } = &mut self.file { - writer - .frame(&data) - .context(crate::error::WriteTtyrec)?; - } - } + match component_future::try_ready!(self + .process + .poll() + .context(crate::error::Subprocess)) + { + Some(tokio_pty_process_stream::Event::CommandStart { + .. + }) => { + if self.raw_screen.is_none() { + self.raw_screen = Some( + crossterm::RawScreen::into_raw_mode() + .context(crate::error::ToRawMode)?, + ); } - Ok(component_future::Async::DidWork) } - Some(crate::resize::Event::Resize(_)) => { - Ok(component_future::Async::DidWork) + Some(tokio_pty_process_stream::Event::CommandExit { .. }) => { + self.done = true; } + Some(tokio_pty_process_stream::Event::Output { data }) => { + self.record_bytes(&data); + if let FileState::Open { writer } = &mut self.file { + writer.frame(&data).context(crate::error::WriteTtyrec)?; + } + } + Some(tokio_pty_process_stream::Event::Resize { .. }) => {} None => { if !self.done { unreachable!() } // don't return final event here - wait until we are done // writing all data to the file (see poll_write_file) - Ok(component_future::Async::DidWork) } } + Ok(component_future::Async::DidWork) } fn poll_write_terminal(&mut self) -> component_future::Poll<(), Error> { diff --git a/src/cmd/stream.rs b/src/cmd/stream.rs index 9d2cf83..b4f1a26 100644 --- a/src/cmd/stream.rs +++ b/src/cmd/stream.rs @@ -119,7 +119,8 @@ struct StreamSession< S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static, > { client: crate::client::Client<S>, - process: crate::resize::ResizingProcess<crate::async_stdin::Stdin>, + process: + tokio_pty_process_stream::ResizingProcess<crate::async_stdin::Stdin>, stdout: tokio::io::Stdout, buffer: crate::term::Buffer, sent_local: usize, @@ -148,7 +149,7 @@ impl<S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static> // let input = tokio::io::stdin(); let input = crate::async_stdin::Stdin::new(); - let process = crate::resize::ResizingProcess::new( + let process = tokio_pty_process_stream::ResizingProcess::new( tokio_pty_process_stream::Process::new(cmd, args, input), ); @@ -235,34 +236,33 @@ impl<S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static> } fn poll_read_process(&mut self) -> component_future::Poll<(), Error> { - match component_future::try_ready!(self.process.poll()) { - Some(crate::resize::Event::Process(e)) => { - match e { - tokio_pty_process_stream::Event::CommandStart { - .. - } => { - if self.raw_screen.is_none() { - self.raw_screen = Some( - crossterm::RawScreen::into_raw_mode() - .context(crate::error::ToRawMode)?, - ); - } - } - tokio_pty_process_stream::Event::CommandExit { - .. - } => { - self.done = true; - } - tokio_pty_process_stream::Event::Output { data } => { - self.record_bytes(&data); - } + match component_future::try_ready!(self + .process + .poll() + .context(crate::error::Subprocess)) + { + Some(tokio_pty_process_stream::Event::CommandStart { + .. + }) => { + if self.raw_screen.is_none() { + self.raw_screen = Some( + crossterm::RawScreen::into_raw_mode() + .context(crate::error::ToRawMode)?, + ); } - Ok(component_future::Async::DidWork) } - Some(crate::resize::Event::Resize(size)) => { - self.client - .send_message(crate::protocol::Message::resize(&size)); - Ok(component_future::Async::DidWork) + Some(tokio_pty_process_stream::Event::CommandExit { .. }) => { + self.done = true; + } + Some(tokio_pty_process_stream::Event::Output { data }) => { + self.record_bytes(&data); + } + Some(tokio_pty_process_stream::Event::Resize { + size: (rows, cols), + }) => { + self.client.send_message(crate::protocol::Message::resize( + &crate::term::Size { rows, cols }, + )); } None => { if !self.done { @@ -270,9 +270,9 @@ impl<S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static> } // don't return final event here - wait until we are done // sending all data to the server (see poll_write_server) - Ok(component_future::Async::DidWork) } } + Ok(component_future::Async::DidWork) } fn poll_write_terminal(&mut self) -> component_future::Poll<(), Error> { diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index 67e3507..0e4e197 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -190,7 +190,12 @@ struct WatchSession< key_reader: crate::key_reader::KeyReader, list_client: crate::client::Client<S>, - resizer: crate::resize::Resizer, + resizer: Box< + dyn futures::stream::Stream< + Item = (u16, u16), + Error = crate::error::Error, + > + Send, + >, state: State<S>, raw_screen: Option<crossterm::RawScreen>, needs_redraw: bool, @@ -212,7 +217,11 @@ impl<S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static> key_reader: crate::key_reader::KeyReader::new(), list_client, - resizer: crate::resize::Resizer::new(), + resizer: Box::new( + tokio_terminal_resize::resizes() + .flatten_stream() + .context(crate::error::Resize), + ), state: State::new(), raw_screen: None, needs_redraw: true, @@ -577,8 +586,9 @@ impl<S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static> ]; fn poll_resizer(&mut self) -> component_future::Poll<(), Error> { - let size = component_future::try_ready!(self.resizer.poll()).unwrap(); - self.resize(size)?; + let (rows, cols) = + component_future::try_ready!(self.resizer.poll()).unwrap(); + self.resize(crate::term::Size { rows, cols })?; Ok(component_future::Async::DidWork) } diff --git a/src/error.rs b/src/error.rs index 087bc72..e6e4530 100644 --- a/src/error.rs +++ b/src/error.rs @@ -274,6 +274,11 @@ pub enum Error { #[snafu(display("failed to read ttyrec: {}", source))] ReadTtyrec { source: ttyrec::Error }, + #[snafu(display("failed to poll for terminal resizing: {}", source))] + Resize { + source: tokio_terminal_resize::Error, + }, + #[snafu(display( "failed to resolve address {}:{}: {}", host, diff --git a/src/main.rs b/src/main.rs index e0db244..d85ebda 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,6 @@ mod error; mod key_reader; mod oauth; mod protocol; -mod resize; mod server; mod session_list; mod term; diff --git a/src/resize.rs b/src/resize.rs deleted file mode 100644 index d792708..0000000 --- a/src/resize.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::prelude::*; - -pub struct Resizer { - winches: - Box<dyn futures::stream::Stream<Item = (), Error = Error> + Send>, - sent_initial_size: bool, -} - -impl Resizer { - pub fn new() -> Self { - let winches = tokio_signal::unix::Signal::new( - tokio_signal::unix::libc::SIGWINCH, - ) - .flatten_stream() - .map(|_| ()) - .context(crate::error::SigWinchHandler); - Self { - winches: Box::new(winches), - sent_initial_size: false, - } - } -} - -#[must_use = "streams do nothing unless polled"] -impl futures::stream::Stream for Resizer { - type Item = crate::term::Size; - type Error = Error; - - fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> { - if !self.sent_initial_size { - self.sent_initial_size = true; - return Ok(futures::Async::Ready( - Some(crate::term::Size::get()?), - )); - } - let _ = futures::try_ready!(self.winches.poll()); - Ok(futures::Async::Ready(Some(crate::term::Size::get()?))) - } -} - -pub enum Event<R: tokio::io::AsyncRead + 'static> { - Process( - <tokio_pty_process_stream::Process<R> as futures::stream::Stream>::Item - ), - Resize(crate::term::Size), -} - -pub struct ResizingProcess<R: tokio::io::AsyncRead + 'static> { - process: tokio_pty_process_stream::Process<R>, - resizer: Resizer, -} - -impl<R: tokio::io::AsyncRead + 'static> ResizingProcess<R> { - pub fn new(process: tokio_pty_process_stream::Process<R>) -> Self { - Self { - process, - resizer: Resizer::new(), - } - } -} - -impl<R: tokio::io::AsyncRead + 'static> ResizingProcess<R> { - const POLL_FNS: - &'static [&'static dyn for<'a> Fn( - &'a mut Self, - ) - -> component_future::Poll< - Option<Event<R>>, - Error, - >] = &[&Self::poll_resize, &Self::poll_process]; - - fn poll_resize( - &mut self, - ) -> component_future::Poll<Option<Event<R>>, Error> { - let size = component_future::try_ready!(self.resizer.poll()).unwrap(); - self.process.resize(size.rows, size.cols); - Ok(component_future::Async::Ready(Some(Event::Resize(size)))) - } - - fn poll_process( - &mut self, - ) -> component_future::Poll<Option<Event<R>>, Error> { - Ok(component_future::Async::Ready( - component_future::try_ready!(self - .process - .poll() - .context(crate::error::Subprocess)) - .map(Event::Process), - )) - } -} - -#[must_use = "streams do nothing unless polled"] -impl<R: tokio::io::AsyncRead + 'static> futures::stream::Stream - for ResizingProcess<R> -{ - type Item = Event<R>; - type Error = Error; - - fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> { - component_future::poll_stream(self, Self::POLL_FNS) - } -} |