From 38c5538186f6de20de7abad672df86765915076c Mon Sep 17 00:00:00 2001 From: Gabby Grinslade Date: Sun, 27 Dec 2020 18:43:56 -0800 Subject: [PATCH] fix winit build --- src/bridge/mod.rs | 552 ++++++++++++++++---------------- src/window/winit/layouts/mod.rs | 15 +- 2 files changed, 288 insertions(+), 279 deletions(-) diff --git a/src/bridge/mod.rs b/src/bridge/mod.rs index 3567201..6f54043 100644 --- a/src/bridge/mod.rs +++ b/src/bridge/mod.rs @@ -1,65 +1,69 @@ -mod events; -mod handler; -mod ui_commands; - -use std::env; -use std::path::Path; -use std::process::Stdio; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; - -use crossfire::mpsc::{RxUnbounded, TxUnbounded}; -use log::{error, info, warn}; -use nvim_rs::{create::tokio as create, UiAttachOptions}; -use rmpv::Value; -use tokio::process::Command; -use tokio::runtime::Runtime; - -use crate::error_handling::ResultPanicExplanation; -use crate::settings::*; -use crate::window::window_geometry_or_default; -pub use events::*; -use handler::NeovimHandler; -pub use ui_commands::UiCommand; - -#[cfg(windows)] -fn set_windows_creation_flags(cmd: &mut Command) { - cmd.creation_flags(0x0800_0000); // CREATE_NO_WINDOW -} - -#[cfg(windows)] -fn platform_build_nvim_cmd(bin: &str) -> Option { - if env::args().any(|arg| arg == "--wsl") { - let mut cmd = Command::new("wsl"); - cmd.arg(bin); - Some(cmd) +mod events; +mod handler; +mod ui_commands; + +use std::env; +use std::path::Path; +use std::process::Stdio; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + +use crossfire::mpsc::{RxUnbounded, TxUnbounded}; +use log::{error, info, warn}; +use nvim_rs::{create::tokio as create, UiAttachOptions}; +use rmpv::Value; +use tokio::process::Command; +use tokio::runtime::Runtime; + +use crate::error_handling::ResultPanicExplanation; +use crate::settings::*; +use crate::window::window_geometry_or_default; +pub use events::*; +use handler::NeovimHandler; +pub use ui_commands::UiCommand; + +#[cfg(windows)] +fn set_windows_creation_flags(cmd: &mut Command) { + cmd.creation_flags(0x0800_0000); // CREATE_NO_WINDOW +} + +#[cfg(windows)] +fn platform_build_nvim_cmd(bin: &str) -> Option { + if env::args().any(|arg| arg == "--wsl") { + let mut cmd = Command::new("wsl"); + cmd.arg(bin); + Some(cmd) } else if Path::new(&bin).exists() { - Some(Command::new(bin)) + Some(Command::new(bin)) } else { None - } -} - -#[cfg(unix)] -fn platform_build_nvim_cmd(bin: &str) -> Option { - if Path::new(&bin).exists() { - Some(Command::new(bin)) - } else { - None - } -} - -fn build_nvim_cmd() -> Command { - if let Ok(path) = env::var("NEOVIM_BIN") { - if let Some(cmd) = platform_build_nvim_cmd(&path) { - return cmd; - } else { - warn!("NEOVIM_BIN is invalid falling back to first bin in PATH"); - } - } + } +} + +#[cfg(unix)] +fn platform_build_nvim_cmd(bin: &str) -> Option { + if Path::new(&bin).exists() { + Some(Command::new(bin)) + } else { + None + } +} + +fn build_nvim_cmd() -> Command { + if let Ok(path) = env::var("NEOVIM_BIN") { + if let Some(cmd) = platform_build_nvim_cmd(&path) { + return cmd; + } else { + warn!("NEOVIM_BIN is invalid falling back to first bin in PATH"); + } + } #[cfg(windows)] if env::args().any(|arg| arg == "--wsl") { - if let Ok(output) = std::process::Command::new("wsl").arg("which").arg("nvim").output() { + if let Ok(output) = std::process::Command::new("wsl") + .arg("which") + .arg("nvim") + .output() + { if output.status.success() { let path = String::from_utf8(output.stdout).unwrap(); let mut cmd = Command::new("wsl"); @@ -74,42 +78,42 @@ fn build_nvim_cmd() -> Command { std::process::exit(1); } } - if let Ok(path) = which::which("nvim") { - if let Some(cmd) = platform_build_nvim_cmd(path.to_str().unwrap()) { - cmd - } else { - error!("nvim does not have proper permissions!"); - std::process::exit(1); - } - } else { - error!("nvim not found!"); - std::process::exit(1); - } -} - -pub fn build_neovide_command(channel: u64, num_args: u64, command: &str, event: &str) -> String { - let nargs: String = if num_args > 1 { - "+".to_string() - } else { - num_args.to_string() - }; - if num_args == 0 { - return format!( - "command! -nargs={} -complete=expression {} call rpcnotify({}, 'neovide.{}')", - nargs, command, channel, event - ); - } else { - return format!( - "command! -nargs={} -complete=expression {} call rpcnotify({}, 'neovide.{}', )", - nargs, command, channel, event - ); - }; -} - -pub fn create_nvim_command() -> Command { - let mut cmd = build_nvim_cmd(); - - cmd.arg("--embed") + if let Ok(path) = which::which("nvim") { + if let Some(cmd) = platform_build_nvim_cmd(path.to_str().unwrap()) { + cmd + } else { + error!("nvim does not have proper permissions!"); + std::process::exit(1); + } + } else { + error!("nvim not found!"); + std::process::exit(1); + } +} + +pub fn build_neovide_command(channel: u64, num_args: u64, command: &str, event: &str) -> String { + let nargs: String = if num_args > 1 { + "+".to_string() + } else { + num_args.to_string() + }; + if num_args == 0 { + return format!( + "command! -nargs={} -complete=expression {} call rpcnotify({}, 'neovide.{}')", + nargs, command, channel, event + ); + } else { + return format!( + "command! -nargs={} -complete=expression {} call rpcnotify({}, 'neovide.{}', )", + nargs, command, channel, event + ); + }; +} + +pub fn create_nvim_command() -> Command { + let mut cmd = build_nvim_cmd(); + + cmd.arg("--embed") .args(SETTINGS.neovim_arguments.iter().skip(1)); #[cfg(not(debug_assertions))] @@ -117,184 +121,184 @@ pub fn create_nvim_command() -> Command { #[cfg(debug_assertions)] cmd.stderr(Stdio::inherit()); - - #[cfg(windows)] - set_windows_creation_flags(&mut cmd); - - cmd -} - -async fn start_neovim_runtime( - ui_command_sender: TxUnbounded, - ui_command_receiver: RxUnbounded, - redraw_event_sender: TxUnbounded, - running: Arc, -) { - let (width, height) = window_geometry_or_default(); - let handler = NeovimHandler::new(ui_command_sender.clone(), redraw_event_sender.clone()); - let (mut nvim, io_handler, _) = create::new_child_cmd(&mut create_nvim_command(), handler) - .await - .unwrap_or_explained_panic("Could not locate or start neovim process"); - - if nvim.get_api_info().await.is_err() { - error!("Cannot get neovim api info, either neovide is launched with an unknown command line option or neovim version not supported!"); - std::process::exit(-1); - } - - let close_watcher_running = running.clone(); - tokio::spawn(async move { - info!("Close watcher started"); - match io_handler.await { - Err(join_error) => error!("Error joining IO loop: '{}'", join_error), - Ok(Err(error)) => { - if !error.is_channel_closed() { - error!("Error: '{}'", error); - } - } - Ok(Ok(())) => {} - }; - close_watcher_running.store(false, Ordering::Relaxed); - }); - - if let Ok(Value::Integer(correct_version)) = nvim.eval("has(\"nvim-0.4\")").await { - if correct_version.as_i64() != Some(1) { - error!("Neovide requires version 0.4 or higher"); - std::process::exit(0); - } - } else { - error!("Neovide requires version 0.4 or higher"); - std::process::exit(0); - }; - - nvim.set_var("neovide", Value::Boolean(true)) - .await - .unwrap_or_explained_panic("Could not communicate with neovim process"); - - if let Err(command_error) = nvim.command("runtime! ginit.vim").await { - nvim.command(&format!( - "echomsg \"error encountered in ginit.vim {:?}\"", - command_error - )) - .await - .ok(); - } - - nvim.set_client_info( - "neovide", - vec![ - (Value::from("major"), Value::from(0u64)), - (Value::from("minor"), Value::from(6u64)), - ], - "ui", - vec![], - vec![], - ) - .await - .ok(); - - let neovide_channel: u64 = nvim - .list_chans() - .await - .ok() - .and_then(|channel_values| parse_channel_list(channel_values).ok()) - .and_then(|channel_list| { - channel_list.iter().find_map(|channel| match channel { - ChannelInfo { - id, - client: Some(ClientInfo { name, .. }), - .. - } if name == "neovide" => Some(*id), - _ => None, - }) - }) - .unwrap_or(0); - - info!( - "Neovide registered to nvim with channel id {}", - neovide_channel - ); - - #[cfg(windows)] - nvim.command(&build_neovide_command( - neovide_channel, - 0, - "NeovideRegisterRightClick", - "register_right_click", - )) - .await - .ok(); - - #[cfg(windows)] - nvim.command(&build_neovide_command( - neovide_channel, - 0, - "NeovideUnregisterRightClick", - "unregister_right_click", - )) - .await - .ok(); - - nvim.set_option("lazyredraw", Value::Boolean(false)) - .await - .ok(); - - let mut options = UiAttachOptions::new(); - options.set_linegrid_external(true); - if env::args().any(|arg| arg == "--multiGrid") || env::var("NeovideMultiGrid").is_ok() { - options.set_multigrid_external(true); - } - options.set_rgb(true); - nvim.ui_attach(width as i64, height as i64, &options) - .await - .unwrap_or_explained_panic("Could not attach ui to neovim process"); - - info!("Neovim process attached"); - - let nvim = Arc::new(nvim); - - let ui_command_running = running.clone(); - let input_nvim = nvim.clone(); - tokio::spawn(async move { - loop { - if !ui_command_running.load(Ordering::Relaxed) { - break; - } - - match ui_command_receiver.recv().await { - Ok(ui_command) => { - let input_nvim = input_nvim.clone(); - tokio::spawn(async move { - ui_command.execute(&input_nvim).await; - }); - } - Err(_) => { - ui_command_running.store(false, Ordering::Relaxed); - break; - } - } - } - }); - - SETTINGS.read_initial_values(&nvim).await; - SETTINGS.setup_changed_listeners(&nvim).await; -} - -pub struct Bridge { - _runtime: Runtime, // Necessary to keep runtime running -} - -pub fn start_bridge( - ui_command_sender: TxUnbounded, - ui_command_receiver: RxUnbounded, - redraw_event_sender: TxUnbounded, - running: Arc, -) -> Bridge { - let runtime = Runtime::new().unwrap(); - runtime.spawn(start_neovim_runtime( - ui_command_sender, - ui_command_receiver, - redraw_event_sender, - running, - )); - Bridge { _runtime: runtime } -} + + #[cfg(windows)] + set_windows_creation_flags(&mut cmd); + + cmd +} + +async fn start_neovim_runtime( + ui_command_sender: TxUnbounded, + ui_command_receiver: RxUnbounded, + redraw_event_sender: TxUnbounded, + running: Arc, +) { + let (width, height) = window_geometry_or_default(); + let handler = NeovimHandler::new(ui_command_sender.clone(), redraw_event_sender.clone()); + let (mut nvim, io_handler, _) = create::new_child_cmd(&mut create_nvim_command(), handler) + .await + .unwrap_or_explained_panic("Could not locate or start neovim process"); + + if nvim.get_api_info().await.is_err() { + error!("Cannot get neovim api info, either neovide is launched with an unknown command line option or neovim version not supported!"); + std::process::exit(-1); + } + + let close_watcher_running = running.clone(); + tokio::spawn(async move { + info!("Close watcher started"); + match io_handler.await { + Err(join_error) => error!("Error joining IO loop: '{}'", join_error), + Ok(Err(error)) => { + if !error.is_channel_closed() { + error!("Error: '{}'", error); + } + } + Ok(Ok(())) => {} + }; + close_watcher_running.store(false, Ordering::Relaxed); + }); + + if let Ok(Value::Integer(correct_version)) = nvim.eval("has(\"nvim-0.4\")").await { + if correct_version.as_i64() != Some(1) { + error!("Neovide requires version 0.4 or higher"); + std::process::exit(0); + } + } else { + error!("Neovide requires version 0.4 or higher"); + std::process::exit(0); + }; + + nvim.set_var("neovide", Value::Boolean(true)) + .await + .unwrap_or_explained_panic("Could not communicate with neovim process"); + + if let Err(command_error) = nvim.command("runtime! ginit.vim").await { + nvim.command(&format!( + "echomsg \"error encountered in ginit.vim {:?}\"", + command_error + )) + .await + .ok(); + } + + nvim.set_client_info( + "neovide", + vec![ + (Value::from("major"), Value::from(0u64)), + (Value::from("minor"), Value::from(6u64)), + ], + "ui", + vec![], + vec![], + ) + .await + .ok(); + + let neovide_channel: u64 = nvim + .list_chans() + .await + .ok() + .and_then(|channel_values| parse_channel_list(channel_values).ok()) + .and_then(|channel_list| { + channel_list.iter().find_map(|channel| match channel { + ChannelInfo { + id, + client: Some(ClientInfo { name, .. }), + .. + } if name == "neovide" => Some(*id), + _ => None, + }) + }) + .unwrap_or(0); + + info!( + "Neovide registered to nvim with channel id {}", + neovide_channel + ); + + #[cfg(windows)] + nvim.command(&build_neovide_command( + neovide_channel, + 0, + "NeovideRegisterRightClick", + "register_right_click", + )) + .await + .ok(); + + #[cfg(windows)] + nvim.command(&build_neovide_command( + neovide_channel, + 0, + "NeovideUnregisterRightClick", + "unregister_right_click", + )) + .await + .ok(); + + nvim.set_option("lazyredraw", Value::Boolean(false)) + .await + .ok(); + + let mut options = UiAttachOptions::new(); + options.set_linegrid_external(true); + if env::args().any(|arg| arg == "--multiGrid") || env::var("NeovideMultiGrid").is_ok() { + options.set_multigrid_external(true); + } + options.set_rgb(true); + nvim.ui_attach(width as i64, height as i64, &options) + .await + .unwrap_or_explained_panic("Could not attach ui to neovim process"); + + info!("Neovim process attached"); + + let nvim = Arc::new(nvim); + + let ui_command_running = running.clone(); + let input_nvim = nvim.clone(); + tokio::spawn(async move { + loop { + if !ui_command_running.load(Ordering::Relaxed) { + break; + } + + match ui_command_receiver.recv().await { + Ok(ui_command) => { + let input_nvim = input_nvim.clone(); + tokio::spawn(async move { + ui_command.execute(&input_nvim).await; + }); + } + Err(_) => { + ui_command_running.store(false, Ordering::Relaxed); + break; + } + } + } + }); + + SETTINGS.read_initial_values(&nvim).await; + SETTINGS.setup_changed_listeners(&nvim).await; +} + +pub struct Bridge { + _runtime: Runtime, // Necessary to keep runtime running +} + +pub fn start_bridge( + ui_command_sender: TxUnbounded, + ui_command_receiver: RxUnbounded, + redraw_event_sender: TxUnbounded, + running: Arc, +) -> Bridge { + let runtime = Runtime::new().unwrap(); + runtime.spawn(start_neovim_runtime( + ui_command_sender, + ui_command_receiver, + redraw_event_sender, + running, + )); + Bridge { _runtime: runtime } +} diff --git a/src/window/winit/layouts/mod.rs b/src/window/winit/layouts/mod.rs index 68b2b28..e8fc43d 100644 --- a/src/window/winit/layouts/mod.rs +++ b/src/window/winit/layouts/mod.rs @@ -9,13 +9,18 @@ impl From> for Modifiers { fn from(state: Option) -> Modifiers { if let Some(modifiers) = state { Modifiers { - shift: state.shift(), - control: state.ctrl(), - meta: state.alt(), - logo: state.logo(), + shift: modifiers.shift(), + control: modifiers.ctrl(), + meta: modifiers.alt(), + logo: modifiers.logo(), } } else { - Modifiers::new(false, false, false, false) + Modifiers { + shift: false, + control: false, + meta: false, + logo: false, + } } } }