From 1d9aea0ad68c5dc41e8c421b05440d1237dd1ee4 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 4 Dec 2021 02:20:11 -0500 Subject: handle terminal resizing --- src/bin/ttyrec/main.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'src') 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>), Stdout(std::io::Result>), + Resize((u16, u16)), +} + +async fn resize(event_w: &async_std::channel::Sender) { + 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), Write(Result, 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?; + } } } -- cgit v1.2.3-54-g00ecf