Detect terminal resize in termion backend

Using the chan_signal crate
This commit is contained in:
Alexandre Bury 2016-12-13 22:10:00 -08:00
parent ea3dde33ec
commit 858067ef6b
3 changed files with 37 additions and 14 deletions

View File

@ -11,16 +11,24 @@ readme = "Readme.md"
repository = "https://github.com/gyscos/Cursive" repository = "https://github.com/gyscos/Cursive"
version = "0.3.5" version = "0.3.5"
[build-dependencies]
[build-dependencies.skeptic] [build-dependencies.skeptic]
optional = true optional = true
version = "0.6" version = "0.6"
[dependencies] [dependencies]
chan = "0.1.18"
chan-signal = "0.1"
odds = "0.2" odds = "0.2"
toml = "0.2" toml = "0.2"
unicode-segmentation = "0.1" unicode-segmentation = "0.1"
unicode-width = "0.1" unicode-width = "0.1"
[dependencies.bear-lib-terminal]
optional = true
version = "1.3.1"
[dependencies.ncurses] [dependencies.ncurses]
features = ["wide"] features = ["wide"]
optional = true optional = true
@ -35,10 +43,6 @@ version = "0.7"
optional = true optional = true
version = "1.1.1" version = "1.1.1"
[dependencies.bear-lib-terminal]
optional = true
version = "1.3.1"
[dev-dependencies] [dev-dependencies]
rand = "0.3" rand = "0.3"
skeptic = "0.6" skeptic = "0.6"

View File

@ -1,5 +1,7 @@
extern crate termion; extern crate termion;
extern crate chan_signal;
use ::backend; use ::backend;
use ::event::{Event, Key}; use ::event::{Event, Key};
use self::termion::color as tcolor; use self::termion::color as tcolor;
@ -11,9 +13,9 @@ use std::cell::Cell;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use std::io::Write; use std::io::Write;
use std::sync::mpsc;
use std::thread; use std::thread;
use std::time; use std::time;
use chan;
use ::theme; use ::theme;
@ -22,8 +24,9 @@ pub struct Concrete {
current_style: Cell<theme::ColorStyle>, current_style: Cell<theme::ColorStyle>,
colors: BTreeMap<i16, (Box<tcolor::Color>, Box<tcolor::Color>)>, colors: BTreeMap<i16, (Box<tcolor::Color>, Box<tcolor::Color>)>,
input: mpsc::Receiver<Event>, input: chan::Receiver<Event>,
timeout: Option<time::Duration>, resize: chan::Receiver<chan_signal::Signal>,
timeout: Option<u32>,
} }
trait Effectable { trait Effectable {
@ -75,17 +78,18 @@ impl Concrete {
impl backend::Backend for Concrete { impl backend::Backend for Concrete {
fn init() -> Self { fn init() -> Self {
print!("{}", termion::cursor::Hide); print!("{}", termion::cursor::Hide);
let resize = chan_signal::notify(&[chan_signal::Signal::WINCH]);
let terminal = ::std::io::stdout().into_raw_mode().unwrap(); let terminal = ::std::io::stdout().into_raw_mode().unwrap();
let (sender, receiver) = mpsc::channel(); let (sender, receiver) = chan::async();
// TODO: use signal_chan crate // TODO: use signal_chan crate
thread::spawn(move || { thread::spawn(move || {
for key in ::std::io::stdin().keys() { for key in ::std::io::stdin().keys() {
if let Ok(key) = key { if let Ok(key) = key {
if sender.send(map_key(key)).is_err() { sender.send(map_key(key))
break;
}
} }
} }
}); });
@ -95,6 +99,7 @@ impl backend::Backend for Concrete {
current_style: Cell::new(theme::ColorStyle::Background), current_style: Cell::new(theme::ColorStyle::Background),
colors: BTreeMap::new(), colors: BTreeMap::new(),
input: receiver, input: receiver,
resize: resize,
timeout: None, timeout: None,
}; };
@ -167,16 +172,27 @@ impl backend::Backend for Concrete {
// TODO: handle async refresh, when no input is entered. // TODO: handle async refresh, when no input is entered.
// Could be done with a timeout on the event polling, // Could be done with a timeout on the event polling,
// if it was supportedd. // if it was supportedd.
self.timeout = Some(time::Duration::from_millis(1000 / fps as u64)); self.timeout = Some(1000 / fps as u32);
} }
fn poll_event(&self) -> Event { fn poll_event(&self) -> Event {
// TODO: select! on the input and SIGWINCH signal channel. // TODO: select! on the input and SIGWINCH signal channel.
// TODO: also handle timeout... recv_timeout? // TODO: also handle timeout... recv_timeout?
let input = &self.input;
let resize = &self.resize;
if let Some(timeout) = self.timeout { if let Some(timeout) = self.timeout {
self.input.recv_timeout(timeout).unwrap_or(Event::Refresh) let timeout = chan::after_ms(timeout);
chan_select!{
timeout.recv() => return Event::Refresh,
resize.recv() => return Event::WindowResize,
input.recv() -> input => return input.unwrap(),
}
} else { } else {
self.input.recv().unwrap() chan_select!{
resize.recv() => return Event::WindowResize,
input.recv() -> input => return input.unwrap(),
}
} }
} }
} }

View File

@ -64,6 +64,9 @@ extern crate unicode_segmentation;
extern crate unicode_width; extern crate unicode_width;
extern crate odds; extern crate odds;
#[macro_use]
extern crate chan;
macro_rules! println_stderr( macro_rules! println_stderr(
($($arg:tt)*) => { { ($($arg:tt)*) => { {
use ::std::io::Write; use ::std::io::Write;