aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-10-27 15:47:32 -0400
committerJesse Luehrs <doy@tozt.net>2019-10-27 15:47:32 -0400
commit5309b3182a30d0555137fbe9fba21ed1d06a91d0 (patch)
treeccba0ec63dd1d305080309eb933032aefe823767
parent4bd939fdf7716bebfe7d13e587f5f6e3ea77e4b4 (diff)
downloadteleterm-5309b3182a30d0555137fbe9fba21ed1d06a91d0.tar.gz
teleterm-5309b3182a30d0555137fbe9fba21ed1d06a91d0.zip
move resizing out into a separate crate
-rw-r--r--Cargo.lock19
-rw-r--r--Cargo.toml3
-rw-r--r--src/cmd/record.rs58
-rw-r--r--src/cmd/stream.rs58
-rw-r--r--src/cmd/watch.rs18
-rw-r--r--src/error.rs5
-rw-r--r--src/main.rs1
-rw-r--r--src/resize.rs103
8 files changed, 93 insertions, 172 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0f4d7a3..9948535 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1648,6 +1648,7 @@ dependencies = [
"tokio",
"tokio-pty-process-stream",
"tokio-signal",
+ "tokio-terminal-resize",
"tokio-tls",
"ttyrec",
"twoway",
@@ -1825,9 +1826,9 @@ dependencies = [
[[package]]
name = "tokio-pty-process-stream"
-version = "0.1.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d5702467cedd1b8180d3aef8d6e195ed3a6151ddca36b3b6d4c57e65b5e0c85"
+checksum = "87c73e73b3907c8a3142162c28ca75a4a941f1f737f3bd31e3faeb6608f2d9f8"
dependencies = [
"component-future",
"futures",
@@ -1835,6 +1836,7 @@ dependencies = [
"snafu",
"tokio",
"tokio-pty-process",
+ "tokio-terminal-resize",
]
[[package]]
@@ -1898,6 +1900,19 @@ dependencies = [
]
[[package]]
+name = "tokio-terminal-resize"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "901915a5bf94a2ae7189de1af32da3161a80efc4609dd36ec8eba570e5c04ec4"
+dependencies = [
+ "futures",
+ "snafu",
+ "term_size",
+ "tokio",
+ "tokio-signal",
+]
+
+[[package]]
name = "tokio-threadpool"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 9f44de0..9941011 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,8 +33,9 @@ reqwest = "0.9.22"
serde = "1"
snafu = { version = "0.5", features = ["rust_1_30", "futures-01"], default_features = false }
tokio = { version = "0.1.22", features = ["codec", "fs", "io", "reactor", "rt-full", "sync", "tcp", "timer"], default_features = false }
-tokio-pty-process-stream = "0.1"
+tokio-pty-process-stream = "0.2"
tokio-signal = "0.2"
+tokio-terminal-resize = "0.1"
tokio-tls = "0.2"
ttyrec = "0.1"
twoway = "0.2"
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)
- }
-}