From 5f33bb16071f68313c12a2fe9a06514bade894f4 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 15 Oct 2019 05:48:00 -0400 Subject: send initial terminal size on process start sending it on connect meant that the terminal size wouldn't be set at all if there was a problem connecting to the server, which confuses programs running in the pty --- src/client.rs | 28 ++++++++++++++++------------ src/cmd/stream.rs | 8 ++++++-- src/cmd/watch.rs | 11 +++++++++-- src/process.rs | 5 +++-- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/client.rs b/src/client.rs index 7b4aa6f..af58e68 100644 --- a/src/client.rs +++ b/src/client.rs @@ -51,9 +51,10 @@ enum WriteSocket< } pub enum Event { + Start(crate::term::Size), ServerMessage(crate::protocol::Message), Disconnect, - Connect(crate::term::Size), + Connect(), Resize(crate::term::Size), } @@ -74,7 +75,6 @@ pub struct Client< buffer_size: usize, term_type: String, - size: Option, heartbeat_timer: tokio::timer::Interval, reconnect_timer: Option, @@ -89,6 +89,7 @@ pub struct Client< on_login: Vec, to_send: std::collections::VecDeque, + started: bool, } impl @@ -162,7 +163,6 @@ impl buffer_size, term_type, - size: None, heartbeat_timer, reconnect_timer: None, @@ -175,6 +175,7 @@ impl on_login: on_login.to_vec(), to_send: std::collections::VecDeque::new(), + started: false, } } @@ -241,13 +242,11 @@ impl crate::protocol::FramedWriter::new(ws, self.buffer_size), ); - self.size = Some(crate::term::Size::get()?); - self.to_send.clear(); self.send_message(crate::protocol::Message::login_plain( &self.username, &self.term_type, - self.size.as_ref().unwrap(), + &crate::term::Size::get()?, )); self.reset_reconnect_timer(); @@ -266,9 +265,7 @@ impl for msg in &self.on_login { self.to_send.push_back(msg.clone()); } - Ok(crate::component_future::Poll::Event(Event::Connect( - self.size.clone().unwrap(), - ))) + Ok(crate::component_future::Poll::Event(Event::Connect())) } crate::protocol::Message::Heartbeat => { Ok(crate::component_future::Poll::DidWork) @@ -440,14 +437,21 @@ impl &mut self, ) -> Result> { if let Some(winches) = &mut self.winches { + if !self.started { + self.started = true; + return Ok(crate::component_future::Poll::Event( + Event::Start(crate::term::Size::get()?), + )); + } + match winches.poll()? { futures::Async::Ready(Some(_)) => { - self.size = Some(crate::term::Size::get()?); + let size = crate::term::Size::get()?; self.send_message(crate::protocol::Message::resize( - self.size.as_ref().unwrap(), + &size, )); Ok(crate::component_future::Poll::Event(Event::Resize( - self.size.clone().unwrap(), + size, ))) } futures::Async::Ready(None) => unreachable!(), diff --git a/src/cmd/stream.rs b/src/cmd/stream.rs index 1e60a25..3afc9eb 100644 --- a/src/cmd/stream.rs +++ b/src/cmd/stream.rs @@ -195,11 +195,14 @@ impl crate::client::Event::Disconnect => { Ok(crate::component_future::Poll::DidWork) } - crate::client::Event::Connect(size) => { - self.sent_remote = 0; + crate::client::Event::Start(size) => { self.process.resize(size); Ok(crate::component_future::Poll::DidWork) } + crate::client::Event::Connect() => { + self.sent_remote = 0; + Ok(crate::component_future::Poll::DidWork) + } crate::client::Event::ServerMessage(..) => { // we don't expect to ever see a server message once we // start streaming, so if one comes through, assume @@ -239,6 +242,7 @@ impl .context(crate::error::ToRawMode)?, ); } + self.process.resize(crate::term::Size::get()?); } crate::process::Event::CommandExit(..) => { self.done = true; diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index 6ec3c4d..43d14a0 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -564,10 +564,13 @@ impl match self.list_client.poll()? { futures::Async::Ready(Some(e)) => { match e { + crate::client::Event::Start(size) => { + self.resize(size)?; + } crate::client::Event::Disconnect => { self.reconnect(true)?; } - crate::client::Event::Connect(_) => { + crate::client::Event::Connect() => { self.list_client.send_message( crate::protocol::Message::list_sessions(), ); @@ -603,10 +606,14 @@ impl match client.poll()? { futures::Async::Ready(Some(e)) => { match e { + crate::client::Event::Start(_) => { + // watch clients don't respond to resize events + unreachable!(); + } crate::client::Event::Disconnect => { self.reconnect(true)?; } - crate::client::Event::Connect(_) => {} + crate::client::Event::Connect() => {} crate::client::Event::ServerMessage(msg) => { self.watch_server_message(msg)?; } diff --git a/src/process.rs b/src/process.rs index 70ad256..d70b207 100644 --- a/src/process.rs +++ b/src/process.rs @@ -82,10 +82,11 @@ impl Process { >] = &[ // order is important here - checking command_exit first so that we // don't try to read from a process that has already exited, which - // causes an error - &Self::poll_resize, + // causes an error. also, poll_resize needs to happen after + // poll_command_start, or else the pty might not be initialized. &Self::poll_command_start, &Self::poll_command_exit, + &Self::poll_resize, &Self::poll_read_stdin, &Self::poll_write_stdin, &Self::poll_read_stdout, -- cgit v1.2.3-54-g00ecf