aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-04 02:20:11 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-04 02:20:11 -0500
commit1d9aea0ad68c5dc41e8c421b05440d1237dd1ee4 (patch)
tree9c622d6f0f5247469b6b27d8db79916e1c9a393c /src
parent33cc13b554e6f4cc6e139b0eecf5c6e697433a9d (diff)
downloadttyrec-bin-1d9aea0ad68c5dc41e8c421b05440d1237dd1ee4.tar.gz
ttyrec-bin-1d9aea0ad68c5dc41e8c421b05440d1237dd1ee4.zip
handle terminal resizing
Diffstat (limited to 'src')
-rw-r--r--src/bin/ttyrec/main.rs40
1 files changed, 39 insertions, 1 deletions
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?;
+ }
}
}