Add a check on macOS to warn the user about possible SecureInput-related issues.
This commit is contained in:
parent
80f12194db
commit
2c8c28087d
23
src/check.rs
23
src/check.rs
|
@ -17,11 +17,11 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// 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
|
||||
}
|
|
@ -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.");
|
||||
|
|
|
@ -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::<i32>().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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<String>;
|
||||
|
|
Loading…
Reference in New Issue
Block a user