diff --git a/src/config/mod.rs b/src/config/mod.rs index 58ab626..7e4d1c0 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -159,6 +159,10 @@ fn default_post_inject_delay() -> u64 { 100 } +fn default_wait_for_modifiers_release() -> bool { + false +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Configs { #[serde(default = "default_name")] @@ -283,6 +287,9 @@ pub struct Configs { #[serde(default = "default_modulo_path")] pub modulo_path: Option, + + #[serde(default = "default_wait_for_modifiers_release")] + pub wait_for_modifiers_release: bool, } // Macro used to validate config fields diff --git a/src/engine.rs b/src/engine.rs index 1dd2cd6..81e4fa5 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -231,6 +231,13 @@ impl< m.triggers[trigger_offset].chars().count() as i32 + 1 // Count also the separator }; + // If configured to do so, wait until the modifier keys are released (or timeout) so + // that we avoid unwanted interactions. As an example, see: + // https://github.com/federico-terzi/espanso/issues/470 + if config.wait_for_modifiers_release { + crate::keyboard::wait_for_modifiers_release(); + } + if !skip_delete { self.keyboard_manager.delete_string(&config, char_count); } diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index 7a5c2ca..d9f11a4 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -18,6 +18,7 @@ */ use crate::config::Configs; +use log::warn; use serde::{Deserialize, Serialize}; #[cfg(target_os = "windows")] @@ -71,3 +72,19 @@ pub fn get_manager() -> impl KeyboardManager { pub fn get_manager() -> impl KeyboardManager { macos::MacKeyboardManager {} } + +// These methods are used to wait until all modifiers are released (or timeout occurs) +pub fn wait_for_modifiers_release() { + #[cfg(target_os = "windows")] + let released = crate::keyboard::windows::wait_for_modifiers_release(); + + #[cfg(target_os = "macos")] + let released = crate::keyboard::macos::wait_for_modifiers_release(); + + #[cfg(target_os = "linux")] + let released = true; // NOOP on linux (at least for now) + + if !released { + warn!("Wait for modifiers release timed out! Please release your modifiers keys (CTRL, CMD, ALT, SHIFT) after typing the trigger"); + } +}