aboutsummaryrefslogtreecommitdiffstats
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
parent33cc13b554e6f4cc6e139b0eecf5c6e697433a9d (diff)
downloadttyrec-bin-1d9aea0ad68c5dc41e8c421b05440d1237dd1ee4.tar.gz
ttyrec-bin-1d9aea0ad68c5dc41e8c421b05440d1237dd1ee4.zip
handle terminal resizing
-rw-r--r--Cargo.lock14
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/ttyrec/main.rs40
3 files changed, 55 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a139d79..521d21c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/Cargo.toml b/Cargo.toml
index ebdb3f9..1802667 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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?;
+ }
}
}