From b32b88ca8ea97b09f96351c241ba501a90a40bf4 Mon Sep 17 00:00:00 2001 From: sgoudham Date: Sun, 31 Jul 2022 23:51:09 +0100 Subject: [PATCH] feat: Configure click_through as command line argument --- src/cmd_line.rs | 26 +++++++++++++++++++++++++- src/window/mouse_manager.rs | 20 ++++++++++++-------- src/window/settings.rs | 2 +- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/cmd_line.rs b/src/cmd_line.rs index c91ac00..290fddd 100644 --- a/src/cmd_line.rs +++ b/src/cmd_line.rs @@ -24,6 +24,8 @@ pub struct CmdLineSettings { pub x11_wm_class: String, // Disable open multiple files as tabs pub no_tabs: bool, + // Replicate macOS behaviour where first click is not registered + pub click_through: bool, } impl Default for CmdLineSettings { @@ -43,6 +45,7 @@ impl Default for CmdLineSettings { multi_grid: false, no_idle: false, srgb: true, + click_through: false, // Command-line arguments with environment variable fallback neovim_bin: None, wayland_app_id: String::new(), @@ -105,6 +108,11 @@ pub fn handle_command_line_arguments(args: Vec) -> Result<(), String> { .long("wsl") .help("Run in WSL") ) + .arg( + Arg::new("click_through") + .long("click-through") + .help("On first mouse click, move the cursor to location of mouse click. DISCLAIMER: Providing this flag on non-macOS systems will not change anything") + ) // Command-line flags with environment variable fallback .arg( Arg::new("frame") @@ -186,6 +194,10 @@ pub fn handle_command_line_arguments(args: Vec) -> Result<(), String> { no_fork: matches.is_present("nofork"), remote_tcp: matches.value_of("remote_tcp").map(|i| i.to_owned()), wsl: matches.is_present("wsl"), + #[cfg(target_os = "macos")] + click_through: matches.is_present("click_through"), + #[cfg(not(target_os = "macos"))] + click_through: true, // Command-line flags with environment variable fallback frame: match matches.value_of("frame") { Some(val) => Frame::from_string(val.to_string()), @@ -197,7 +209,7 @@ pub fn handle_command_line_arguments(args: Vec) -> Result<(), String> { maximized: matches.is_present("maximized") || std::env::var("NEOVIDE_MAXIMIZED").is_ok(), multi_grid: matches.is_present("multi_grid") || std::env::var("NEOVIDE_MULTIGRID").is_ok(), no_idle: matches.is_present("noidle") || std::env::var("NEOVIDE_NO_IDLE").is_ok(), - // Srgb is enabled by default, so set it to false if nosrgb or NOEVIDE_NO_SRGB is set + // Srgb is enabled by default, so set it to false if nosrgb or NEOVIDE_NO_SRGB is set srgb: !(matches.is_present("nosrgb") || std::env::var("NEOVIDE_NO_SRGB").is_ok()), // Command-line arguments with environment variable fallback neovim_bin: matches @@ -345,6 +357,18 @@ mod tests { assert!(SETTINGS.get::().log_to_file); } + #[test] + fn test_click_through() { + let args: Vec = vec!["neovide", "--click-through"] + .iter() + .map(|s| s.to_string()) + .collect(); + + let _accessing_settings = ACCESSING_SETTINGS.lock().unwrap(); + handle_command_line_arguments(args).expect("Could not parse arguments"); + assert!(SETTINGS.get::().click_through) + } + #[test] fn test_frameless_flag() { let args: Vec = vec!["neovide", "--frame=full"] diff --git a/src/window/mouse_manager.rs b/src/window/mouse_manager.rs index aa30dd3..84db9d6 100644 --- a/src/window/mouse_manager.rs +++ b/src/window/mouse_manager.rs @@ -13,7 +13,7 @@ use glutin::{ }, PossiblyCurrent, WindowedContext, }; -use log::info; + use skia_safe::Rect; use crate::{ @@ -87,8 +87,8 @@ pub struct MouseManager { mouse_hidden: bool, pub enabled: bool, - // Not exactly a mouse setting but ideally needs to exist for some state - current_window_focused: bool, + // Not a mouse setting but needs to exist to track the state of WindowFocusedEvents + window_focused: bool, } impl MouseManager { @@ -104,7 +104,7 @@ impl MouseManager { window_details_under_mouse: None, mouse_hidden: false, enabled: true, - current_window_focused: false, + window_focused: false, } } @@ -220,7 +220,10 @@ impl MouseManager { self.relative_position }; - if click_through || !self.current_window_focused { + // Only register command if: + // a) click through is enabled + // b) the current window doesn't have focus + if click_through || !self.window_focused { EVENT_AGGREGATOR.send(UiCommand::Serial(SerialCommand::MouseButton { button: button_text.clone(), action, @@ -450,7 +453,7 @@ impl MouseManager { Event::WindowEvent { event: WindowEvent::Focused(focused), .. - } => self.current_window_focused = *focused, + } => self.window_focused = *focused, Event::WindowEvent { event: WindowEvent::CursorMoved { position, .. }, .. @@ -517,8 +520,9 @@ impl MouseManager { window_settings.click_through, ); - // Always reset focused to false to prevent all mouse inputs not working - self.current_window_focused = false; + // We want to always reset window_focused to false to ensure that subsequent mouse events + // are properly registered after the initial window focus. + self.window_focused = false; } Event::WindowEvent { event: diff --git a/src/window/settings.rs b/src/window/settings.rs index 5b16adc..788eb63 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -28,7 +28,7 @@ impl Default for WindowSettings { hide_mouse_when_typing: false, touch_deadzone: 6.0, touch_drag_timeout: 0.17, - click_through: false + click_through: SETTINGS.get::().click_through, } } }