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_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")]
fn set_windows_creation_flags(cmd: &mut Command) {
use std::os::windows::process::CommandExt;
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
}
fn main() {
env_logger::from_env(LoggerEnv::default().default_filter_or("warn")).init();
panic::set_hook(Box::new(|_| {
exit(1);
}));
fn create_nvim_command() -> Command {
let mut cmd = Command::new("nvim");
cmd.arg("--embed")
.args(std::env::args().skip(1))
.stderr(Stdio::inherit());
@ -58,8 +40,14 @@ fn main() {
#[cfg(target_os = "windows")]
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 receiver = session.start_event_loop_channel();
let join_handle = session.take_dispatch_guard();
let mut nvim = Neovim::new(session);
let mut options = UiAttachOptions::new();
options.set_cmdline_external(false);
@ -68,12 +56,31 @@ fn main() {
options.set_rgb(true);
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 || {
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));
}

@ -109,7 +109,7 @@ impl Renderer {
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 x = grid_x as f32 * self.font_width;
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);
self.paint.set_color(style.background(default_colors).to_color());
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 {
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) {
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();
@ -159,8 +171,11 @@ impl Renderer {
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 {
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();
@ -309,12 +324,17 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, nvim: Neovim, initial_size: (u64, u64
..
} => {
let input_type = if delta > 0.0 {
"up"
Some("up")
} else if delta < 0.0 {
Some("down")
} else {
"down"
None
};
let (grid_x, grid_y) = mouse_pos;
nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input");
if let Some(input_type) = input_type {
let (grid_x, grid_y) = mouse_pos;
nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input");
}
}
Event::EventsCleared => {

Loading…
Cancel
Save