From 232e80f55a5fd1e1ab94a14f10cb22fe091a2493 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Wed, 10 Jun 2020 20:07:06 +0200 Subject: [PATCH 1/3] Fix app name extraction that returned garbage with certain apps on macOS. Fix #291 --- src/system/macos.rs | 63 ++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/src/system/macos.rs b/src/system/macos.rs index c3ccf43..584c26e 100644 --- a/src/system/macos.rs +++ b/src/system/macos.rs @@ -91,12 +91,6 @@ impl MacSystemManager { /// Check whether an application is currently holding the Secure Input. /// Return None if no application has claimed SecureInput, Some((AppName, AppPath)) otherwise. pub fn get_secure_input_application() -> Option<(String, String)> { - use regex::Regex; - - lazy_static! { - static ref APP_REGEX: Regex = Regex::new("/([^/]+).app/").unwrap(); - }; - unsafe { let pid = MacSystemManager::get_secure_input_pid(); @@ -112,26 +106,59 @@ impl MacSystemManager { if let Ok(path) = string { if !path.trim().is_empty() { let process = path.trim().to_string(); - let caps = APP_REGEX.captures(&process); - let app_name = if let Some(caps) = caps { - caps.get(1).map_or("", |m| m.as_str()).to_owned() + let app_name = if let Some(name) = Self::get_app_name_from_path(&process) { + name } else { process.to_owned() }; - Some((app_name, process)) - } else { - None + return Some((app_name, process)); } - } else { - None } - } else { - None } - } else { - None } + + None + } + } + + fn get_app_name_from_path(path: &str) -> Option { + use regex::Regex; + + lazy_static! { + static ref APP_REGEX: Regex = Regex::new("/([^/]+).(app|bundle)/").unwrap(); + }; + + let caps = APP_REGEX.captures(&path); + if let Some(caps) = caps { + Some(caps.get(1).map_or("", |m| m.as_str()).to_owned()) + } else { + None } } } + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_app_name_from_path() { + let app_name = MacSystemManager::get_app_name_from_path("/Applications/iTerm.app/Contents/MacOS/iTerm2"); + assert_eq!(app_name.unwrap(), "iTerm") + } + + #[test] + fn test_get_app_name_from_path_no_app_name() { + let app_name = MacSystemManager::get_app_name_from_path("/another/directory"); + assert!(app_name.is_none()) + } + + #[test] + fn test_get_app_name_from_path_security_bundle() { + let app_name = MacSystemManager::get_app_name_from_path("/System/Library/Frameworks/Security.framework/Versions/A/MachServices/SecurityAgent.bundle/Contents/MacOS/SecurityAgent"); + assert_eq!(app_name.unwrap(), "SecurityAgent") + } +} + From 470f8d62217b519faa7aeb7dd6e9e7444b97c8f4 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Wed, 10 Jun 2020 20:21:18 +0200 Subject: [PATCH 2/3] Inject user path in Plist file when registering on macOS. Fix #233 --- src/res/mac/com.federicoterzi.espanso.plist | 5 +++++ src/sysdaemon.rs | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/res/mac/com.federicoterzi.espanso.plist b/src/res/mac/com.federicoterzi.espanso.plist index 0728b20..e537367 100644 --- a/src/res/mac/com.federicoterzi.espanso.plist +++ b/src/res/mac/com.federicoterzi.espanso.plist @@ -4,6 +4,11 @@ Label com.federicoterzi.espanso + EnvironmentVariables + + PATH + {{{PATH}}} + ProgramArguments {{{espanso_path}}} diff --git a/src/sysdaemon.rs b/src/sysdaemon.rs index 4d4c055..de54983 100644 --- a/src/sysdaemon.rs +++ b/src/sysdaemon.rs @@ -61,6 +61,12 @@ pub fn register(_config_set: ConfigSet) { espanso_path.to_str().unwrap_or_default(), ); + // Copy the user PATH variable and inject it in the Plist file so that + // it gets loaded by Launchd. + // To see why this is necessary: https://github.com/federico-terzi/espanso/issues/233 + let user_path = std::env::var("PATH").unwrap_or("".to_owned()); + let plist_content = plist_content.replace("{{{PATH}}}", &user_path); + std::fs::write(plist_file.clone(), plist_content).expect("Unable to write plist file"); println!("Entry created correctly!") From e6bbf08a9dfa555059b6dfb30470f09a409565b9 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Wed, 10 Jun 2020 20:32:46 +0200 Subject: [PATCH 3/3] Release SHIFT key if pressed when expanding on macOS. Fix #279 --- native/libmacbridge/bridge.mm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/native/libmacbridge/bridge.mm b/native/libmacbridge/bridge.mm index 3e2d7e5..1ddd549 100644 --- a/native/libmacbridge/bridge.mm +++ b/native/libmacbridge/bridge.mm @@ -87,6 +87,16 @@ void send_string(const char * string) { // Send the event + // Check if the shift key is down, and if so, release it + // To see why: https://github.com/federico-terzi/espanso/issues/279 + if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, 0x38)) { + CGEventRef e2 = CGEventCreateKeyboardEvent(NULL, 0x38, false); + CGEventPost(kCGHIDEventTap, e2); + CFRelease(e2); + + usleep(2000); + } + // Because of a bug ( or undocumented limit ) of the CGEventKeyboardSetUnicodeString method // the string gets truncated after 20 characters, so we need to send multiple events.