Better keyboard input, config cleanup, TERM env, exit with child

This commit is contained in:
mars 2022-10-04 13:32:43 -06:00
parent 12b3bf2f14
commit 4d3c84596d
1 changed files with 71 additions and 30 deletions

View File

@ -8,9 +8,11 @@ use alacritty_terminal::sync::FairMutex;
use alacritty_terminal::term::color::{Colors, Rgb};
use alacritty_terminal::tty::Pty;
use alacritty_terminal::Term;
use mio_extras::channel::Sender;
use mio_extras::channel::Sender as MioSender;
use softbuffer::GraphicsContext;
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Arc;
use std::thread::JoinHandle;
use winit::event::{Event, WindowEvent};
@ -19,20 +21,32 @@ use winit::window::{Window, WindowBuilder};
static FONT_DATA: &[u8] = include_bytes!("/usr/share/fonts/local/TamzenForPowerline10x20r.bdf");
pub struct TermListener {}
pub struct TermListener {
sender: Sender<TermEvent>,
}
impl TermListener {
pub fn new(sender: Sender<TermEvent>) -> Self {
Self { sender }
}
}
impl EventListener for TermListener {
fn send_event(&self, event: TermEvent) {}
fn send_event(&self, event: TermEvent) {
self.sender.send(event).unwrap();
}
}
pub struct App {
font: bdf::Font,
graphics: GraphicsContext<Window>,
should_quit: bool,
cell_width: usize,
cell_height: usize,
colors: Colors,
term_loop: JoinHandle<(TermEventLoop<Pty, TermListener>, TermState)>,
term_channel: Sender<TermMsg>,
term_channel: MioSender<TermMsg>,
term_events: Receiver<TermEvent>,
term: Arc<FairMutex<Term<TermListener>>>,
}
@ -53,26 +67,34 @@ impl App {
false,
);
let term_config = Default::default();
let term_events = TermListener {};
let (sender, term_events) = channel();
let pty_config = PtyConfig {
shell: Some(alacritty_terminal::config::Program::Just(
"/usr/bin/fish".to_string(),
)),
working_directory: None,
hold: false,
let mut env = HashMap::<String, String>::default();
env.insert("TERM".to_string(), "xterm".to_string());
let term_config = alacritty_terminal::config::Config {
env,
pty_config: PtyConfig {
shell: Some(alacritty_terminal::config::Program::Just(
"/usr/bin/fish".to_string(),
)),
working_directory: None,
hold: false,
},
..Default::default()
};
let term = Term::new(&term_config, term_size, term_events);
let term_listener = TermListener::new(sender.clone());
let term = Term::new(&term_config, term_size, term_listener);
let mut colors = term.colors().to_owned();
let term = FairMutex::new(term);
let term = Arc::new(term);
let pty = alacritty_terminal::tty::new(&pty_config, &term_size, None).unwrap();
let pty = alacritty_terminal::tty::new(&term_config.pty_config, &term_size, None).unwrap();
let term_events = TermListener {};
let term_loop = TermEventLoop::new(term.clone(), term_events, pty, false, false);
let term_listener = TermListener::new(sender);
let term_loop = TermEventLoop::new(term.clone(), term_listener, pty, false, false);
let term_channel = term_loop.channel();
Self::load_colors(&mut colors);
@ -80,15 +102,21 @@ impl App {
Self {
font,
graphics: unsafe { GraphicsContext::new(window).unwrap() },
should_quit: false,
cell_width,
cell_height,
term,
term_channel,
term_events,
colors,
term_loop: term_loop.spawn(),
}
}
pub fn should_quit(&self) -> bool {
self.should_quit
}
pub fn load_colors(color: &mut Colors) {
use NamedColor::*;
@ -163,12 +191,10 @@ impl App {
let term = self.term.lock();
let content = term.renderable_content();
let mut fg_num = 0;
let mut missing_chars = std::collections::HashSet::new();
for cell in content.display_iter.into_iter() {
if let Some(glyph) = self.font.glyphs().get(&cell.c) {
// println!("cell: {:?}", cell);
let term_row = cell.point.line.0 as usize;
let term_col = cell.point.column.0 as usize;
@ -177,11 +203,11 @@ impl App {
let mut px_row = term_row * width * self.cell_height;
if (term_row + 1) * self.cell_height >= height {
if (term_row + 1) * self.cell_height > height {
continue;
}
if (term_col + 1) * self.cell_width >= width {
if (term_col + 1) * self.cell_width > width {
continue;
}
@ -189,7 +215,6 @@ impl App {
let px_start = px_row + term_col * self.cell_width;
for x in 0..self.cell_width {
let color = if glyph.get(x as u32, y as u32) {
fg_num += 1;
fg
} else {
bg
@ -201,11 +226,11 @@ impl App {
px_row += width;
}
} else {
println!("missing char: {}", cell.c);
missing_chars.insert(cell.c);
}
}
log::debug!("FG num: {}", fg_num);
log::debug!("Missing characters: {:?}", missing_chars);
self.graphics
.set_buffer(&buffer, width as u16, height as u16);
@ -225,20 +250,32 @@ impl App {
((rgb.r as u32) << 16) | ((rgb.g as u32) << 8) | (rgb.b as u32)
}
pub fn update(&mut self) {}
pub fn update(&mut self) {
while let Ok(event) = self.term_events.try_recv() {
match event {
TermEvent::Exit => self.should_quit = true,
_ => {}
}
}
}
pub fn on_keyboard_input(&mut self, input: &winit::event::KeyboardInput) {
if input.state == winit::event::ElementState::Pressed {
if let Some(keycode) = input.virtual_keycode {
if let Some(c) = virtual_keycode_to_byte(keycode) {
let bytes = [c];
let cow = Cow::Owned(bytes.into());
self.term_channel.send(TermMsg::Input(cow)).unwrap();
self.on_received_character(c as char);
}
}
}
}
pub fn on_received_character(&mut self, c: char) {
let mut bytes = [0u8; 4];
let len = c.encode_utf8(&mut bytes).len();
let cow = Cow::Owned(bytes[0..len].into());
self.term_channel.send(TermMsg::Input(cow)).unwrap();
}
pub fn on_resize(&mut self, width: u32, height: u32) {
let term_size = alacritty_terminal::term::SizeInfo::new(
width as f32,
@ -335,8 +372,8 @@ fn main() {
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
WindowEvent::KeyboardInput { input, .. } => {
app.on_keyboard_input(&input);
WindowEvent::ReceivedCharacter(c) => {
app.on_received_character(c);
}
WindowEvent::Resized(size) => {
app.on_resize(size.width, size.height);
@ -346,5 +383,9 @@ fn main() {
}
_ => {}
}
if app.should_quit() {
*control_flow = ControlFlow::Exit;
}
});
}