diff --git a/src/config/mod.rs b/src/config/mod.rs index 64b7389..180566e 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -198,7 +198,20 @@ impl Configs { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum BackendType { Inject, - Clipboard + Clipboard, + + // On Linux systems there is a long standing issue with text injection (which + // in general is better than Clipboard copy/pasting) that prevents certain + // apps from correctly handling special characters (such as emojis or accented letters) + // when injected. For this reason, espanso initially defaulted on the Clipboard + // backend on Linux, as it was the most reliable (working in 99% of cases), + // even though it was less efficient and with a few inconveniences (for example, the + // previous clipboard content being overwritten). + // The Auto backend tries to take it a step further, by automatically determining + // when an injection is possible (only ascii characters in the replacement), and falling + // back to the Clipboard backend otherwise. + // Should only be used on Linux systems. + Auto } impl Default for BackendType { // The default backend varies based on the operating system. diff --git a/src/engine.rs b/src/engine.rs index 622f169..ac22cd1 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -189,7 +189,25 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa None }; - match config.backend { + let backend = if config.backend == BackendType::Auto { + if cfg!(target_os = "linux") { + let all_ascii = target_string.chars().all(|c| c.is_ascii()); + if all_ascii { + debug!("All elements of the replacement are ascii, using Inject backend"); + &BackendType::Inject + }else{ + debug!("There are non-ascii characters, using Clipboard backend"); + &BackendType::Clipboard + } + }else{ + warn!("Using Auto backend is only supported on Linux, falling back to Inject backend."); + &BackendType::Inject + } + }else{ + &config.backend + }; + + match backend { BackendType::Inject => { // Send the expected string. On linux, newlines are managed automatically // while on windows and macos, we need to emulate a Enter key press. @@ -217,6 +235,10 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa self.clipboard_manager.set_clipboard(&target_string); self.keyboard_manager.trigger_paste(&config.paste_shortcut); }, + _ => { + error!("Unsupported backend type evaluation."); + return; + } } if let Some(moves) = cursor_rewind {