diff --git a/Cargo.lock b/Cargo.lock index 1d1da14..6774e40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,6 +383,7 @@ version = "1.0.2-dev" dependencies = [ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 18fb853..65c6949 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ harness = false termion = "1.5.5" libc = "0.2.66" atty = "0.2.14" +lazy_static = "1.4" tor-stream = { version = "0.2.0", optional = true } native-tls = { version = "0.2", optional = true } diff --git a/src/lib.rs b/src/lib.rs index 3bb7b66..59132f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,9 @@ #![allow(clippy::while_let_on_iterator)] #![allow(clippy::write_with_newline)] +#[macro_use] +extern crate lazy_static; + #[macro_use] pub mod utils; #[macro_use] diff --git a/src/ui.rs b/src/ui.rs index 966c3ec..ff712c4 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -26,12 +26,14 @@ use crate::{ text::Text, utils, BUG_URL, }; +use lazy_static; +use libc; use std::{ cell::RefCell, io::{stdin, stdout, Result, Stdout, Write}, process::{self, Stdio}, sync::{ - mpsc::{channel, Receiver}, + mpsc::{channel, Receiver, Sender}, Arc, Mutex, }, thread, @@ -65,6 +67,18 @@ const ERR_RAW_MODE: &str = "Fatal Error using Raw Mode."; const ERR_SCREEN: &str = "Fatal Error using Alternate Screen."; const ERR_STDOUT: &str = "Fatal Error writing to STDOUT."; +lazy_static! { + /// Channel to send SIGWINCH (resize) events on, once received. + static ref RESIZE_SENDER: Arc>>> = Arc::new(Mutex::new(None)); +} + +/// Raw resize handler that is called when SIGWINCH is receiver. +fn resize_handler(_: i32) { + if let Some(sender) = &*RESIZE_SENDER.lock().unwrap() { + sender.send(Key::F(5)).unwrap(); + } +} + /// UI is mainly concerned with drawing to the screen, managing the /// active views, and responding to user input. pub struct UI { @@ -535,6 +549,12 @@ impl UI { fn spawn_keyboard_listener() -> KeyReceiver { let (sender, receiver) = channel(); + // Give our resize handler a channel to send events on. + *RESIZE_SENDER.lock().unwrap() = Some(sender.clone()); + unsafe { + libc::signal(libc::SIGWINCH, resize_handler as usize); + } + thread::spawn(move || { for event in stdin().keys() { if let Ok(key) = event { @@ -585,6 +605,8 @@ impl UI { self.process_action(fun(response))?; } } + // F5 = refresh + Action::Keypress(Key::F(5)) => self.dirty = true, Action::Keypress(Key::Left) | Action::Keypress(Key::Backspace) => { if self.focused > 0 { self.dirty = true;