diff options
-rw-r--r-- | Cargo.lock | 14 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/bin/ttyrec/main.rs | 40 |
3 files changed, 55 insertions, 1 deletions
@@ -637,6 +637,18 @@ dependencies = [ ] [[package]] +name = "signal-hook-async-std" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90526e74631c69a79b38212e3d4fda4b00de9d6be56b3cead133bf67ad371af1" +dependencies = [ + "async-io", + "futures-lite", + "libc", + "signal-hook", +] + +[[package]] name = "signal-hook-registry" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -784,6 +796,8 @@ dependencies = [ "libc", "paw", "pty-process", + "signal-hook", + "signal-hook-async-std", "structopt", "terminal_size", "textmode", @@ -11,6 +11,8 @@ async-std = { version = "1.10.0", features = ["unstable"] } libc = "0.2.108" paw = "1.0.0" pty-process = { version = "0.1.1", features = ["backend-async-std"] } +signal-hook = "0.3.10" +signal-hook-async-std = "0.2.1" structopt = { version = "0.3.25", features = ["paw", "wrap_help"] } terminal_size = "0.1.17" textmode = { version = "0.2.0", features = ["async"] } diff --git a/src/bin/ttyrec/main.rs b/src/bin/ttyrec/main.rs index 1db1504..353b0bc 100644 --- a/src/bin/ttyrec/main.rs +++ b/src/bin/ttyrec/main.rs @@ -1,5 +1,6 @@ use async_std::io::{ReadExt as _, WriteExt as _}; use async_std::prelude::FutureExt as _; +use async_std::stream::StreamExt as _; use pty_process::Command as _; #[derive(Debug, structopt::StructOpt)] @@ -26,6 +27,15 @@ fn get_cmd( enum Event { Key(textmode::Result<Option<textmode::Key>>), Stdout(std::io::Result<Vec<u8>>), + Resize((u16, u16)), +} + +async fn resize(event_w: &async_std::channel::Sender<Event>) { + let size = terminal_size::terminal_size().map_or( + (24, 80), + |(terminal_size::Width(w), terminal_size::Height(h))| (h, w), + ); + event_w.send(Event::Resize(size)).await.unwrap(); } async fn async_main(opt: Opt) -> anyhow::Result<()> { @@ -46,6 +56,19 @@ async fn async_main(opt: Opt) -> anyhow::Result<()> { let (event_w, event_r) = async_std::channel::unbounded(); let (input_w, input_r) = async_std::channel::unbounded(); + let (resize_w, resize_r) = async_std::channel::unbounded(); + + { + let mut signals = signal_hook_async_std::Signals::new(&[ + signal_hook::consts::signal::SIGWINCH, + ])?; + let event_w = event_w.clone(); + async_std::task::spawn(async move { + while signals.next().await.is_some() { + resize(&event_w).await; + } + }); + } { let event_w = event_w.clone(); @@ -66,12 +89,14 @@ async fn async_main(opt: Opt) -> anyhow::Result<()> { enum Res { Read(Result<usize, std::io::Error>), Write(Result<Vec<u8>, async_std::channel::RecvError>), + Resize(Result<(u16, u16), async_std::channel::RecvError>), } let mut buf = [0_u8; 4096]; let mut pty = child.pty(); let read = async { Res::Read(pty.read(&mut buf).await) }; let write = async { Res::Write(input_r.recv().await) }; - match read.race(write).await { + let resize = async { Res::Resize(resize_r.recv().await) }; + match read.race(write).race(resize).await { Res::Read(res) => { let res = res.map(|n| buf[..n].to_vec()); let err = res.is_err(); @@ -84,11 +109,21 @@ async fn async_main(opt: Opt) -> anyhow::Result<()> { let bytes = res.unwrap(); pty.write(&bytes).await.unwrap(); } + Res::Resize(res) => { + let size = res.unwrap(); + child + .resize_pty(&pty_process::Size::new( + size.0, size.1, + )) + .unwrap(); + } } } }); } + resize(&event_w).await; + let mut writer = ttyrec::Writer::new(fh); loop { match event_r.recv().await? { @@ -117,6 +152,9 @@ async fn async_main(opt: Opt) -> anyhow::Result<()> { } } }, + Event::Resize((h, w)) => { + resize_w.send((h, w)).await?; + } } } |