better neovim process tracking and separated background/foreground rendering

macos-click-through
Keith Simmons 5 years ago
parent 2844cc2888
commit 186edf1819

@ -24,33 +24,15 @@ use events::parse_neovim_event;
const INITIAL_WIDTH: u64 = 100; const INITIAL_WIDTH: u64 = 100;
const INITIAL_HEIGHT: u64 = 50; const INITIAL_HEIGHT: u64 = 50;
fn nvim_event_loop(receiver: Receiver<(String, Vec<Value>)>, editor: &Arc<Mutex<Editor>>) {
println!("UI thread spawned");
loop {
let (event_name, events) = receiver.recv().expect("Could not receive event.");
let parsed_events = parse_neovim_event(event_name, events).expect("Event parse failed...");
for event in parsed_events {
let mut editor = editor.lock().unwrap();
editor.handle_redraw_event(event);
}
}
}
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
fn set_windows_creation_flags(cmd: &mut Command) { fn set_windows_creation_flags(cmd: &mut Command) {
use std::os::windows::process::CommandExt; use std::os::windows::process::CommandExt;
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
} }
fn main() { fn create_nvim_command() -> Command {
env_logger::from_env(LoggerEnv::default().default_filter_or("warn")).init();
panic::set_hook(Box::new(|_| {
exit(1);
}));
let mut cmd = Command::new("nvim"); let mut cmd = Command::new("nvim");
cmd.arg("--embed") cmd.arg("--embed")
.args(std::env::args().skip(1)) .args(std::env::args().skip(1))
.stderr(Stdio::inherit()); .stderr(Stdio::inherit());
@ -58,8 +40,14 @@ fn main() {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
set_windows_creation_flags(&mut cmd); set_windows_creation_flags(&mut cmd);
cmd
}
fn start_nvim(editor: Arc<Mutex<Editor>>) -> Neovim {
let mut cmd = create_nvim_command();
let mut session = Session::new_child_cmd(&mut cmd).unwrap(); let mut session = Session::new_child_cmd(&mut cmd).unwrap();
let receiver = session.start_event_loop_channel(); let receiver = session.start_event_loop_channel();
let join_handle = session.take_dispatch_guard();
let mut nvim = Neovim::new(session); let mut nvim = Neovim::new(session);
let mut options = UiAttachOptions::new(); let mut options = UiAttachOptions::new();
options.set_cmdline_external(false); options.set_cmdline_external(false);
@ -68,12 +56,31 @@ fn main() {
options.set_rgb(true); options.set_rgb(true);
nvim.ui_attach(INITIAL_WIDTH as i64, INITIAL_HEIGHT as i64, &options).unwrap(); nvim.ui_attach(INITIAL_WIDTH as i64, INITIAL_HEIGHT as i64, &options).unwrap();
let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT))); // Listen to neovim events
thread::spawn(move || {
println!("UI thread spawned");
loop {
let (event_name, events) = receiver.recv().expect("Could not receive event.");
let parsed_events = parse_neovim_event(event_name, events).expect("Event parse failed...");
for event in parsed_events {
let mut editor = editor.lock().unwrap();
editor.handle_redraw_event(event);
}
}
});
let nvim_editor = editor.clone(); // Quit process when nvim exits
thread::spawn(move || { thread::spawn(move || {
nvim_event_loop(receiver, &nvim_editor); join_handle.join();
std::process::exit(0);
}); });
nvim
}
fn main() {
// env_logger::from_env(LoggerEnv::default().default_filter_or("warn")).init();
let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT)));
let nvim = start_nvim(editor.clone());
ui_loop(editor, nvim, (INITIAL_WIDTH, INITIAL_HEIGHT)); ui_loop(editor, nvim, (INITIAL_WIDTH, INITIAL_HEIGHT));
} }

@ -109,7 +109,7 @@ impl Renderer {
Renderer { editor, title, paint, font, shaper, font_width, font_height, cursor_pos, fps_tracker } Renderer { editor, title, paint, font, shaper, font_width, font_height, cursor_pos, fps_tracker }
} }
fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) { fn draw_background(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors) {
let (grid_x, grid_y) = grid_pos; let (grid_x, grid_y) = grid_pos;
let x = grid_x as f32 * self.font_width; let x = grid_x as f32 * self.font_width;
let y = grid_y as f32 * self.font_height; let y = grid_y as f32 * self.font_height;
@ -118,6 +118,13 @@ impl Renderer {
let region = Rect::new(x, y, x + width, y + height); let region = Rect::new(x, y, x + width, y + height);
self.paint.set_color(style.background(default_colors).to_color()); self.paint.set_color(style.background(default_colors).to_color());
canvas.draw_rect(region, &self.paint); canvas.draw_rect(region, &self.paint);
}
fn draw_foreground(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) {
let (grid_x, grid_y) = grid_pos;
let x = grid_x as f32 * self.font_width;
let y = grid_y as f32 * self.font_height;
let width = text.chars().count() as f32 * self.font_width;
if style.underline || style.undercurl { if style.underline || style.undercurl {
let (_, metrics) = self.font.metrics(); let (_, metrics) = self.font.metrics();
@ -141,6 +148,11 @@ impl Renderer {
} }
} }
fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) {
self.draw_background(canvas, text, grid_pos, style, default_colors);
self.draw_foreground(canvas, text, grid_pos, style, default_colors, update_cache);
}
pub fn draw(&mut self, window: &Window, canvas: &mut Canvas) { pub fn draw(&mut self, window: &Window, canvas: &mut Canvas) {
let (draw_commands, title, default_colors, (width, height), cursor_grid_pos, cursor_type, cursor_foreground, cursor_background, cursor_enabled) = { let (draw_commands, title, default_colors, (width, height), cursor_grid_pos, cursor_type, cursor_foreground, cursor_background, cursor_enabled) = {
let editor = self.editor.lock().unwrap(); let editor = self.editor.lock().unwrap();
@ -159,8 +171,11 @@ impl Renderer {
canvas.clear(default_colors.background.clone().unwrap().to_color()); canvas.clear(default_colors.background.clone().unwrap().to_color());
for command in draw_commands.iter() {
self.draw_background(canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors);
}
for command in draw_commands { for command in draw_commands {
self.draw_text(canvas, &command.text, command.grid_position, &command.style, &default_colors, true); self.draw_foreground(canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors, true);
} }
self.fps_tracker.record_frame(); self.fps_tracker.record_frame();
@ -309,13 +324,18 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, nvim: Neovim, initial_size: (u64, u64
.. ..
} => { } => {
let input_type = if delta > 0.0 { let input_type = if delta > 0.0 {
"up" Some("up")
} else if delta < 0.0 {
Some("down")
} else { } else {
"down" None
}; };
if let Some(input_type) = input_type {
let (grid_x, grid_y) = mouse_pos; let (grid_x, grid_y) = mouse_pos;
nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input"); nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input");
} }
}
Event::EventsCleared => { Event::EventsCleared => {
window.request_redraw(); window.request_redraw();

Loading…
Cancel
Save