split ui command into serial and parallel

macos-click-through
Keith Simmons 3 years ago committed by Keith Simmons
parent a6f45a33ca
commit cb0f92688d

@ -8,7 +8,7 @@ use rmpv::Value;
use tokio::task; use tokio::task;
use super::events::{parse_redraw_event, RedrawEvent}; use super::events::{parse_redraw_event, RedrawEvent};
use super::ui_commands::UiCommand; use super::ui_commands::{ParallelCommand, UiCommand};
use crate::bridge::TxWrapper; use crate::bridge::TxWrapper;
use crate::channel_utils::*; use crate::channel_utils::*;
use crate::error_handling::ResultPanicExplanation; use crate::error_handling::ResultPanicExplanation;
@ -66,12 +66,12 @@ impl Handler for NeovimHandler {
#[cfg(windows)] #[cfg(windows)]
"neovide.register_right_click" => { "neovide.register_right_click" => {
let ui_command_sender = ui_command_sender.lock(); let ui_command_sender = ui_command_sender.lock();
ui_command_sender.send(UiCommand::RegisterRightClick).ok(); ui_command_sender.send(ParallelCommand::RegisterRightClick.into()).ok();
} }
#[cfg(windows)] #[cfg(windows)]
"neovide.unregister_right_click" => { "neovide.unregister_right_click" => {
let ui_command_sender = ui_command_sender.lock(); let ui_command_sender = ui_command_sender.lock();
ui_command_sender.send(UiCommand::UnregisterRightClick).ok(); ui_command_sender.send(ParallelCommand::UnregisterRightClick.into()).ok();
} }
_ => {} _ => {}
}); });

@ -22,7 +22,7 @@ use crate::{cmd_line::CmdLineSettings, error_handling::ResultPanicExplanation};
pub use events::*; pub use events::*;
use handler::NeovimHandler; use handler::NeovimHandler;
pub use tx_wrapper::{TxWrapper, WrapTx}; pub use tx_wrapper::{TxWrapper, WrapTx};
pub use ui_commands::UiCommand; pub use ui_commands::{UiCommand, SerialCommand, ParallelCommand, start_ui_command_handler};
#[cfg(windows)] #[cfg(windows)]
fn set_windows_creation_flags(cmd: &mut Command) { fn set_windows_creation_flags(cmd: &mut Command) {
@ -156,7 +156,7 @@ fn connection_mode() -> ConnectionMode {
async fn start_neovim_runtime( async fn start_neovim_runtime(
ui_command_sender: LoggingTx<UiCommand>, ui_command_sender: LoggingTx<UiCommand>,
mut ui_command_receiver: UnboundedReceiver<UiCommand>, ui_command_receiver: UnboundedReceiver<UiCommand>,
redraw_event_sender: LoggingTx<RedrawEvent>, redraw_event_sender: LoggingTx<RedrawEvent>,
running: Arc<AtomicBool>, running: Arc<AtomicBool>,
) { ) {
@ -284,29 +284,7 @@ async fn start_neovim_runtime(
let nvim = Arc::new(nvim); let nvim = Arc::new(nvim);
let ui_command_running = running.clone(); start_ui_command_handler(running.clone(), ui_command_receiver, nvim.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 {
Some(ui_command) => {
let input_nvim = input_nvim.clone();
tokio::spawn(async move {
ui_command.execute(&input_nvim).await;
});
}
None => {
ui_command_running.store(false, Ordering::Relaxed);
break;
}
}
}
});
SETTINGS.read_initial_values(&nvim).await; SETTINGS.read_initial_values(&nvim).await;
SETTINGS.setup_changed_listeners(&nvim).await; SETTINGS.setup_changed_listeners(&nvim).await;
} }

@ -1,24 +1,32 @@
use log::trace; use std::sync::{
Arc,
atomic::{
AtomicBool,
Ordering,
},
};
use log::trace;
#[cfg(windows)] #[cfg(windows)]
use log::error; use log::error;
use nvim_rs::Neovim; use nvim_rs::Neovim;
use tokio::sync::mpsc::{
unbounded_channel,
UnboundedReceiver,
UnboundedSender,
};
use crate::bridge::TxWrapper; use crate::bridge::TxWrapper;
#[cfg(windows)] #[cfg(windows)]
use crate::windows_utils::{ use crate::windows_utils::{
register_rightclick_directory, register_rightclick_file, unregister_rightclick, register_rightclick_directory, register_rightclick_file, unregister_rightclick,
}; };
// Serial commands are any commands which must complete before the next value is sent. This
// includes keyboard and mouse input which would cuase problems if sent out of order.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum UiCommand { pub enum SerialCommand {
Quit,
Resize {
width: u64,
height: u64,
},
Keyboard(String), Keyboard(String),
MouseButton { MouseButton {
button: String, button: String,
@ -39,30 +47,16 @@ pub enum UiCommand {
position: (u32, u32), position: (u32, u32),
modifier_string: String, modifier_string: String,
}, },
FileDrop(String),
FocusLost,
FocusGained,
#[cfg(windows)]
RegisterRightClick,
#[cfg(windows)]
UnregisterRightClick,
} }
impl UiCommand { impl SerialCommand {
pub async fn execute(self, nvim: &Neovim<TxWrapper>) { async fn execute(self, nvim: &Neovim<TxWrapper>) {
match self { match self {
UiCommand::Quit => { SerialCommand::Keyboard(input_command) => {
nvim.command("qa!").await.ok();
}
UiCommand::Resize { width, height } => nvim
.ui_try_resize(width.max(10) as i64, height.max(3) as i64)
.await
.expect("Resize failed"),
UiCommand::Keyboard(input_command) => {
trace!("Keyboard Input Sent: {}", input_command); trace!("Keyboard Input Sent: {}", input_command);
nvim.input(&input_command).await.expect("Input failed"); nvim.input(&input_command).await.expect("Input failed");
} }
UiCommand::MouseButton { SerialCommand::MouseButton {
button, button,
action, action,
grid_id, grid_id,
@ -80,7 +74,7 @@ impl UiCommand {
.await .await
.expect("Mouse Input Failed"); .expect("Mouse Input Failed");
} }
UiCommand::Scroll { SerialCommand::Scroll {
direction, direction,
grid_id, grid_id,
position: (grid_x, grid_y), position: (grid_x, grid_y),
@ -97,8 +91,12 @@ impl UiCommand {
.await .await
.expect("Mouse Scroll Failed"); .expect("Mouse Scroll Failed");
} }
<<<<<<< Updated upstream
UiCommand::Drag { UiCommand::Drag {
button, button,
=======
SerialCommand::Drag {
>>>>>>> Stashed changes
grid_id, grid_id,
position: (grid_x, grid_y), position: (grid_x, grid_y),
modifier_string, modifier_string,
@ -114,19 +112,49 @@ impl UiCommand {
.await .await
.expect("Mouse Drag Failed"); .expect("Mouse Drag Failed");
} }
UiCommand::FocusLost => nvim }
}
}
#[derive(Debug, Clone)]
pub enum ParallelCommand {
Quit,
Resize {
width: u64,
height: u64,
},
FileDrop(String),
FocusLost,
FocusGained,
#[cfg(windows)]
RegisterRightClick,
#[cfg(windows)]
UnregisterRightClick,
}
impl ParallelCommand {
async fn execute(self, nvim: &Neovim<TxWrapper>) {
match self {
ParallelCommand::Quit => {
nvim.command("qa!").await.ok();
}
ParallelCommand::Resize { width, height } => nvim
.ui_try_resize(width.max(10) as i64, height.max(3) as i64)
.await
.expect("Resize failed"),
ParallelCommand::FocusLost => nvim
.command("if exists('#FocusLost') | doautocmd <nomodeline> FocusLost | endif") .command("if exists('#FocusLost') | doautocmd <nomodeline> FocusLost | endif")
.await .await
.expect("Focus Lost Failed"), .expect("Focus Lost Failed"),
UiCommand::FocusGained => nvim ParallelCommand::FocusGained => nvim
.command("if exists('#FocusGained') | doautocmd <nomodeline> FocusGained | endif") .command("if exists('#FocusGained') | doautocmd <nomodeline> FocusGained | endif")
.await .await
.expect("Focus Gained Failed"), .expect("Focus Gained Failed"),
UiCommand::FileDrop(path) => { ParallelCommand::FileDrop(path) => {
nvim.command(format!("e {}", path).as_str()).await.ok(); nvim.command(format!("e {}", path).as_str()).await.ok();
} }
#[cfg(windows)] #[cfg(windows)]
UiCommand::RegisterRightClick => { ParallelCommand::RegisterRightClick => {
if unregister_rightclick() { if unregister_rightclick() {
let msg = "Could not unregister previous menu item. Possibly already registered or not running as Admin?"; let msg = "Could not unregister previous menu item. Possibly already registered or not running as Admin?";
nvim.err_writeln(msg).await.ok(); nvim.err_writeln(msg).await.ok();
@ -144,7 +172,7 @@ impl UiCommand {
} }
} }
#[cfg(windows)] #[cfg(windows)]
UiCommand::UnregisterRightClick => { ParallelCommand::UnregisterRightClick => {
if !unregister_rightclick() { if !unregister_rightclick() {
let msg = "Could not remove context menu items. Possibly already removed or not running as Admin?"; let msg = "Could not remove context menu items. Possibly already removed or not running as Admin?";
nvim.err_writeln(msg).await.ok(); nvim.err_writeln(msg).await.ok();
@ -154,3 +182,72 @@ impl UiCommand {
} }
} }
} }
#[derive(Debug, Clone)]
pub enum UiCommand {
Serial(SerialCommand),
Parallel(ParallelCommand),
}
impl From<SerialCommand> for UiCommand {
fn from(serial: SerialCommand) -> Self {
UiCommand::Serial(serial)
}
}
impl From<ParallelCommand> for UiCommand {
fn from(parallel: ParallelCommand) -> Self {
UiCommand::Parallel(parallel)
}
}
pub fn start_ui_command_handler(running: Arc<AtomicBool>, mut ui_command_receiver: UnboundedReceiver<UiCommand>, nvim: Arc<Neovim<TxWrapper>>) {
let serial_tx = start_serial_command_handler(running, nvim);
tokio::spawn(async move {
loop {
if !running.load(Ordering::Relaxed) {
break;
}
match ui_command_receiver.recv().await {
Some(UiCommand::Serial(serial_command)) =>
serial_tx.send(serial_command).expect("Could not send serial ui command"),
Some(UiCommand::Parallel(parallel_command)) => {
let nvim = nvim.clone();
tokio::spawn(async move {
parallel_command.execute(&nvim).await;
});
}
None => {
running.store(false, Ordering::Relaxed);
break;
}
}
}
});
}
pub fn start_serial_command_handler(running: Arc<AtomicBool>, nvim: Arc<Neovim<TxWrapper>>) -> UnboundedSender<SerialCommand> {
let (serial_tx, serial_rx) = unbounded_channel::<SerialCommand>();
tokio::spawn(async move {
loop {
if !running.load(Ordering::Relaxed) {
break;
}
match serial_rx.recv().await {
Some(serial_command) => {
serial_command.execute(&nvim).await;
},
None => {
running.store(false, Ordering::Relaxed);
break;
},
}
}
});
serial_tx
}

@ -3,7 +3,7 @@ use glutin::keyboard::Key;
use winit::platform::modifier_supplement::KeyEventExtModifierSupplement; use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
use crate::bridge::UiCommand; use crate::bridge::{SerialCommand, UiCommand};
use crate::channel_utils::LoggingTx; use crate::channel_utils::LoggingTx;
use crate::settings::SETTINGS; use crate::settings::SETTINGS;
use crate::window::KeyboardSettings; use crate::window::KeyboardSettings;
@ -74,7 +74,7 @@ impl KeyboardManager {
if key_event.state == ElementState::Pressed { if key_event.state == ElementState::Pressed {
if let Some(keybinding) = self.maybe_get_keybinding(key_event) { if let Some(keybinding) = self.maybe_get_keybinding(key_event) {
self.command_sender self.command_sender
.send(UiCommand::Keyboard(keybinding)) .send(SerialCommand::Keyboard(keybinding).into())
.expect("Could not send keyboard ui command"); .expect("Could not send keyboard ui command");
} }
} }

@ -26,7 +26,7 @@ use glutin::platform::unix::WindowBuilderExtUnix;
use super::settings::WindowSettings; use super::settings::WindowSettings;
use crate::{ use crate::{
bridge::UiCommand, bridge::{ParallelCommand, UiCommand},
channel_utils::*, channel_utils::*,
cmd_line::CmdLineSettings, cmd_line::CmdLineSettings,
editor::DrawCommand, editor::DrawCommand,
@ -102,7 +102,7 @@ impl GlutinWindowWrapper {
pub fn handle_quit(&mut self, running: &Arc<AtomicBool>) { pub fn handle_quit(&mut self, running: &Arc<AtomicBool>) {
if SETTINGS.get::<CmdLineSettings>().remote_tcp.is_none() { if SETTINGS.get::<CmdLineSettings>().remote_tcp.is_none() {
self.ui_command_sender self.ui_command_sender
.send(UiCommand::Quit) .send(ParallelCommand::Quit.into())
.expect("Could not send quit command to bridge"); .expect("Could not send quit command to bridge");
} else { } else {
running.store(false, Ordering::Relaxed); running.store(false, Ordering::Relaxed);
@ -110,11 +110,11 @@ impl GlutinWindowWrapper {
} }
pub fn handle_focus_lost(&mut self) { pub fn handle_focus_lost(&mut self) {
self.ui_command_sender.send(UiCommand::FocusLost).ok(); self.ui_command_sender.send(ParallelCommand::FocusLost.into()).ok();
} }
pub fn handle_focus_gained(&mut self) { pub fn handle_focus_gained(&mut self) {
self.ui_command_sender.send(UiCommand::FocusGained).ok(); self.ui_command_sender.send(ParallelCommand::FocusGained.into()).ok();
REDRAW_SCHEDULER.queue_next_frame(); REDRAW_SCHEDULER.queue_next_frame();
} }
@ -147,9 +147,9 @@ impl GlutinWindowWrapper {
.. ..
} => { } => {
self.ui_command_sender self.ui_command_sender
.send(UiCommand::FileDrop( .send(ParallelCommand::FileDrop(
path.into_os_string().into_string().unwrap(), path.into_os_string().into_string().unwrap(),
)) ).into())
.ok(); .ok();
} }
Event::WindowEvent { Event::WindowEvent {
@ -224,10 +224,10 @@ impl GlutinWindowWrapper {
} }
self.saved_grid_size = Some(grid_size); self.saved_grid_size = Some(grid_size);
self.ui_command_sender self.ui_command_sender
.send(UiCommand::Resize { .send(ParallelCommand::Resize {
width: grid_size.width, width: grid_size.width,
height: grid_size.height, height: grid_size.height,
}) }.into())
.ok(); .ok();
} }

@ -8,8 +8,12 @@ use glutin::{
}; };
use skia_safe::Rect; use skia_safe::Rect;
<<<<<<< Updated upstream
use super::keyboard_manager::KeyboardManager; use super::keyboard_manager::KeyboardManager;
use crate::bridge::UiCommand; use crate::bridge::UiCommand;
=======
use crate::bridge::{SerialCommand, UiCommand};
>>>>>>> Stashed changes
use crate::channel_utils::LoggingTx; use crate::channel_utils::LoggingTx;
use crate::renderer::{Renderer, WindowDrawDetails}; use crate::renderer::{Renderer, WindowDrawDetails};
@ -162,12 +166,19 @@ impl MouseManager {
// If dragging and we haven't already sent a position, send a drag command // If dragging and we haven't already sent a position, send a drag command
if self.dragging.is_some() && has_moved { if self.dragging.is_some() && has_moved {
self.command_sender self.command_sender
<<<<<<< Updated upstream
.send(UiCommand::Drag { .send(UiCommand::Drag {
button: self.dragging.as_ref().unwrap().to_owned(), button: self.dragging.as_ref().unwrap().to_owned(),
grid_id: relevant_window_details.id, grid_id: relevant_window_details.id,
position: self.drag_position.into(), position: self.drag_position.into(),
modifier_string: keyboard_manager.format_modifier_string(true), modifier_string: keyboard_manager.format_modifier_string(true),
}) })
=======
.send(SerialCommand::Drag {
grid_id: relevant_window_details.id,
position: self.drag_position.into(),
}.into())
>>>>>>> Stashed changes
.ok(); .ok();
} else { } else {
// otherwise, update the window_id_under_mouse to match the one selected // otherwise, update the window_id_under_mouse to match the one selected
@ -203,6 +214,7 @@ impl MouseManager {
}; };
self.command_sender self.command_sender
<<<<<<< Updated upstream
.send(UiCommand::MouseButton { .send(UiCommand::MouseButton {
button: button_text.clone(), button: button_text.clone(),
action, action,
@ -210,6 +222,14 @@ impl MouseManager {
position: position.into(), position: position.into(),
modifier_string: keyboard_manager.format_modifier_string(true), modifier_string: keyboard_manager.format_modifier_string(true),
}) })
=======
.send(SerialCommand::MouseButton {
button: button_text.to_string(),
action,
grid_id: details.id,
position: position.into(),
}.into())
>>>>>>> Stashed changes
.ok(); .ok();
} }
@ -238,7 +258,7 @@ impl MouseManager {
}; };
if let Some(input_type) = vertical_input_type { if let Some(input_type) = vertical_input_type {
let scroll_command = UiCommand::Scroll { let scroll_command: UiCommand = SerialCommand::Scroll {
direction: input_type.to_string(), direction: input_type.to_string(),
grid_id: self grid_id: self
.window_details_under_mouse .window_details_under_mouse
@ -246,8 +266,12 @@ impl MouseManager {
.map(|details| details.id) .map(|details| details.id)
.unwrap_or(0), .unwrap_or(0),
position: self.drag_position.into(), position: self.drag_position.into(),
<<<<<<< Updated upstream
modifier_string: keyboard_manager.format_modifier_string(true), modifier_string: keyboard_manager.format_modifier_string(true),
}; };
=======
}.into();
>>>>>>> Stashed changes
for _ in 0..(new_y - previous_y).abs() { for _ in 0..(new_y - previous_y).abs() {
self.command_sender.send(scroll_command.clone()).ok(); self.command_sender.send(scroll_command.clone()).ok();
} }
@ -264,7 +288,7 @@ impl MouseManager {
}; };
if let Some(input_type) = horizontal_input_type { if let Some(input_type) = horizontal_input_type {
let scroll_command = UiCommand::Scroll { let scroll_command: UiCommand = SerialCommand::Scroll {
direction: input_type.to_string(), direction: input_type.to_string(),
grid_id: self grid_id: self
.window_details_under_mouse .window_details_under_mouse
@ -272,8 +296,12 @@ impl MouseManager {
.map(|details| details.id) .map(|details| details.id)
.unwrap_or(0), .unwrap_or(0),
position: self.drag_position.into(), position: self.drag_position.into(),
<<<<<<< Updated upstream
modifier_string: keyboard_manager.format_modifier_string(true), modifier_string: keyboard_manager.format_modifier_string(true),
}; };
=======
}.into();
>>>>>>> Stashed changes
for _ in 0..(new_x - previous_x).abs() { for _ in 0..(new_x - previous_x).abs() {
self.command_sender.send(scroll_command.clone()).ok(); self.command_sender.send(scroll_command.clone()).ok();
} }

Loading…
Cancel
Save