diff --git a/src/event.rs b/src/event.rs index c3c45b3d..246b1f24 100644 --- a/src/event.rs +++ b/src/event.rs @@ -12,4 +12,5 @@ pub enum Event { EvInputUp, EvInputDown, EvInputSelect, + EvResize, } diff --git a/src/main.rs b/src/main.rs index 01a99d5b..cb14f6b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(io)] +extern crate libc; extern crate ncurses; mod util; mod item; @@ -13,15 +14,17 @@ mod orderedvec; use std::sync::Arc; use std::thread; use std::sync::mpsc::channel; +use std::mem; +use std::ptr; use util::eventbox::EventBox; use ncurses::*; - use event::Event; use input::Input; use reader::Reader; use matcher::Matcher; use model::Model; +use libc::{sigemptyset, sigaddset, sigwait, pthread_sigmask}; fn main() { // initialize ncurses @@ -33,7 +36,6 @@ fn main() { noecho(); let mut model = Model::new(); - let eb = Arc::new(EventBox::new()); let (tx_source, rx_source) = channel(); let (tx_matched, rx_matched) = channel(); @@ -50,6 +52,24 @@ fn main() { let eb_clone_input = eb.clone(); let mut input = Input::new(eb_clone_input); + // register terminal resize event, `pthread_sigmask` should be run before any thread. + let mut sigset = unsafe {mem::uninitialized()}; + unsafe { + sigemptyset(&mut sigset); + sigaddset(&mut sigset, libc::SIGWINCH); + pthread_sigmask(libc::SIG_SETMASK, &mut sigset, ptr::null_mut()); + } + + let eb_clone_resize = eb.clone(); + thread::spawn(move || { + // listen to the resize event; + loop { + let mut sig = 0; + let _errno = unsafe {sigwait(&mut sigset, &mut sig)}; + eb_clone_resize.set(Event::EvResize, Box::new(true)); + } + }); + // start running thread::spawn(move || { reader.run(); @@ -110,6 +130,9 @@ fn main() { Event::EvInputDown=> { model.move_line_cursor(1); } + Event::EvResize => { + model.resize(); + } _ => { printw(format!("{}\n", e as i32).as_str()); diff --git a/src/model.rs b/src/model.rs index d5cbeaa4..953bda34 100644 --- a/src/model.rs +++ b/src/model.rs @@ -210,4 +210,16 @@ impl Model { self.print_query(); self.refresh(); } + + // the terminal resizes, so we need to recalculate the margins. + pub fn resize(&mut self) { + clear(); + endwin(); + refresh(); + let mut max_y = 0; + let mut max_x = 0; + getmaxyx(stdscr, &mut max_y, &mut max_x); + self.max_y = max_y; + self.max_x = max_x; + } }