From 270b603e8f0720187845e76bda35f295727ed97c Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Wed, 26 Aug 2020 19:29:45 +0200 Subject: [PATCH] Fix #418 --- src/context/windows.rs | 2 +- src/engine.rs | 22 ++++++++-------------- src/extension/form.rs | 5 ++++- src/guard.rs | 39 +++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/ui/modulo/mod.rs | 3 ++- 6 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 src/guard.rs diff --git a/src/context/windows.rs b/src/context/windows.rs index 6928850..f871f30 100644 --- a/src/context/windows.rs +++ b/src/context/windows.rs @@ -24,11 +24,11 @@ use crate::event::{ActionType, Event, KeyEvent, KeyModifier}; use log::{debug, error, info}; use std::ffi::c_void; use std::fs; +use std::path::{Path, PathBuf}; use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering::Acquire; use std::sync::mpsc::Sender; use std::sync::Arc; -use std::path::{Path, PathBuf}; use widestring::{U16CStr, U16CString}; const BMP_BINARY: &[u8] = include_bytes!("../res/win/espanso.bmp"); diff --git a/src/engine.rs b/src/engine.rs index 3e2a534..3406181 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -25,7 +25,10 @@ use crate::keyboard::KeyboardManager; use crate::matcher::{Match, MatchReceiver}; use crate::protocol::{send_command_or_warn, IPCCommand, Service}; use crate::render::{RenderResult, Renderer}; -use crate::ui::{MenuItem, MenuItemType, UIManager}; +use crate::{ + guard::InjectGuard, + ui::{MenuItem, MenuItemType, UIManager}, +}; use log::{debug, error, info, warn}; use regex::Regex; use std::cell::RefCell; @@ -209,7 +212,7 @@ impl< } // Block espanso from reinterpreting its own actions - self.is_injecting.store(true, Release); + let _inject_guard = InjectGuard::new(self.is_injecting.clone(), &config); let char_count = if trailing_separator.is_none() { m.triggers[trigger_offset].chars().count() as i32 @@ -307,18 +310,6 @@ impl< .set_clipboard(&previous_clipboard_content); } - // On macOS, because the keyinjection is async, we need to wait a bit before - // giving back the control. Otherwise, the injected actions will be handled back - // by espanso itself. - if cfg!(target_os = "macos") { - std::thread::sleep(std::time::Duration::from_millis( - config.mac_post_inject_delay, - )); - } - - // Re-allow espanso to interpret actions - self.is_injecting.store(false, Release); - expansion_data } } @@ -349,6 +340,9 @@ impl< return; } + // Block espanso from reinterpreting its own actions + let _inject_guard = InjectGuard::new(self.is_injecting.clone(), &config); + let last_expansion_data = self.last_expansion_data.borrow(); if let Some(ref last_expansion_data) = *last_expansion_data { let (trigger_string, injected_text_len) = last_expansion_data; diff --git a/src/extension/form.rs b/src/extension/form.rs index 79133f6..c0a3361 100644 --- a/src/extension/form.rs +++ b/src/extension/form.rs @@ -61,7 +61,10 @@ impl super::Extension for FormExtension { } if let Some(icon_path) = crate::context::get_icon_path() { - form_config.insert(Value::from("icon"), Value::from(icon_path.to_string_lossy().to_string())); + form_config.insert( + Value::from("icon"), + Value::from(icon_path.to_string_lossy().to_string()), + ); } let serialized_config: String = diff --git a/src/guard.rs b/src/guard.rs new file mode 100644 index 0000000..2f5b1f6 --- /dev/null +++ b/src/guard.rs @@ -0,0 +1,39 @@ +use crate::config::Configs; +use log::debug; +use std::sync::atomic::Ordering::Release; +use std::sync::{atomic::AtomicBool, Arc}; + +pub struct InjectGuard { + is_injecting: Arc, + mac_post_inject_delay: u64, +} + +impl InjectGuard { + pub fn new(is_injecting: Arc, config: &Configs) -> Self { + debug!("enabling inject guard"); + + // Enable the injecting block + is_injecting.store(true, Release); + + Self { + is_injecting, + mac_post_inject_delay: config.mac_post_inject_delay, + } + } +} + +impl Drop for InjectGuard { + fn drop(&mut self) { + debug!("releasing inject guard"); + + // On macOS, because the keyinjection is async, we need to wait a bit before + // giving back the control. Otherwise, the injected actions will be handled back + // by espanso itself. + if cfg!(target_os = "macos") { + std::thread::sleep(std::time::Duration::from_millis(self.mac_post_inject_delay)); + } + + // Re-allow espanso to interpret actions + self.is_injecting.store(false, Release); + } +} diff --git a/src/main.rs b/src/main.rs index bb9c0ed..6158d38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,6 +63,7 @@ mod edit; mod engine; mod event; mod extension; +mod guard; mod keyboard; mod matcher; mod package; diff --git a/src/ui/modulo/mod.rs b/src/ui/modulo/mod.rs index 008956d..1a19d2d 100644 --- a/src/ui/modulo/mod.rs +++ b/src/ui/modulo/mod.rs @@ -71,7 +71,8 @@ impl ModuloManager { if let Some(ref modulo_path) = self.modulo_path { let mut command = Command::new(modulo_path); - command.args(args) + command + .args(args) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped());