diff --git a/src/check.rs b/src/check.rs
index 146b170..daed087 100644
--- a/src/check.rs
+++ b/src/check.rs
@@ -17,11 +17,11 @@
* along with espanso. If not, see .
*/
-// This functions are used to check if the required dependencies are satisfied
+// This functions are used to check if the required dependencies and conditions are satisfied
// before starting espanso
#[cfg(target_os = "linux")]
-pub fn check_dependencies() -> bool {
+pub fn check_preconditions() -> bool {
use std::process::Command;
let mut result = true;
@@ -48,13 +48,26 @@ pub fn check_dependencies() -> bool {
}
#[cfg(target_os = "macos")]
-pub fn check_dependencies() -> bool {
- // Nothing to do here
+pub fn check_preconditions() -> bool {
+ // Make sure no app is currently using secure input.
+ let secure_input_app = crate::system::macos::MacSystemManager::get_secure_input_application();
+
+ if let Some((app_name, process)) = secure_input_app {
+ eprintln!("WARNING: An application is currently using SecureInput and might prevent espanso from working correctly.");
+ eprintln!();
+ eprintln!("APP: {}", app_name);
+ eprintln!("PROC: {}", process);
+ eprintln!();
+ eprintln!("Please close it or disable SecureInput for that application (most apps that use it have a");
+ eprintln!("setting to disable it).");
+ eprintln!("Until then, espanso might not work as expected.");
+ }
+
true
}
#[cfg(target_os = "windows")]
-pub fn check_dependencies() -> bool {
+pub fn check_preconditions() -> bool {
// Nothing needed on windows
true
}
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index cc59337..ebc371d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1037,9 +1037,9 @@ fn release_lock(lock_file: File) {
lock_file.unlock().unwrap()
}
-/// Used to make sure all the required dependencies are present before starting espanso.
+/// Used to make sure all the required dependencies and conditions are satisfied before starting espanso.
fn precheck_guard() {
- let satisfied = check::check_dependencies();
+ let satisfied = check::check_preconditions();
if !satisfied {
println!();
println!("Pre-check was not successful, espanso could not be started.");
diff --git a/src/system/macos.rs b/src/system/macos.rs
index fc867d1..8a04e77 100644
--- a/src/system/macos.rs
+++ b/src/system/macos.rs
@@ -74,4 +74,71 @@ 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 std::process::Command;
+ use regex::Regex;
+
+ let output = Command::new("ioreg")
+ .arg("-d")
+ .arg("1")
+ .arg("-k")
+ .arg("IOConsoleUsers")
+ .arg("-w")
+ .arg("0")
+ .output();
+
+ lazy_static! {
+ static ref PID_REGEX: Regex = Regex::new("\"kCGSSessionSecureInputPID\"=(\\d+)").unwrap();
+ };
+
+ lazy_static! {
+ static ref APP_REGEX: Regex = Regex::new("/([^/]+).app/").unwrap();
+ };
+
+ if let Ok(output) = output {
+ let output_str = String::from_utf8_lossy(output.stdout.as_slice());
+ let caps = PID_REGEX.captures(&output_str);
+
+ if let Some(caps) = caps {
+ // Get the PID of the process that is handling SecureInput
+ let pid_str = caps.get(1).map_or("", |m| m.as_str());
+ let pid = pid_str.parse::().expect("Invalid pid value");
+
+ // Find the process that is handling the SecureInput
+ let output = Command::new("ps")
+ .arg("-p")
+ .arg(pid.to_string())
+ .arg("-o")
+ .arg("command=")
+ .output();
+
+ if let Ok(output) = output {
+ let output_str = String::from_utf8_lossy(output.stdout.as_slice());
+
+ if !output_str.trim().is_empty() {
+ let process = output_str.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()
+ }else{
+ process.to_owned()
+ };
+
+ Some((app_name, process))
+ }else{
+ None
+ }
+ }else{ // Can't obtain process name
+ None
+ }
+ }else{ // No process is holding SecureInput
+ None
+ }
+ }else{ // Can't execute the query to the IOKit registry
+ None
+ }
+ }
}
\ No newline at end of file
diff --git a/src/system/mod.rs b/src/system/mod.rs
index fadcf5a..a0bd25a 100644
--- a/src/system/mod.rs
+++ b/src/system/mod.rs
@@ -24,7 +24,7 @@ mod windows;
mod linux;
#[cfg(target_os = "macos")]
-mod macos;
+pub mod macos;
pub trait SystemManager {
fn get_current_window_title(&self) -> Option;