From 861030ab7a328c5d13cc0651813a37d4837874d3 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Wed, 23 Oct 2019 20:55:54 +0200 Subject: [PATCH] Fix bug that prevented espanso detect from working correctly on macOS. Fix #91 --- native/libmacbridge/bridge.h | 5 ++++ native/libmacbridge/bridge.mm | 6 +++++ src/bridge/macos.rs | 1 + src/main.rs | 47 +++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/native/libmacbridge/bridge.h b/native/libmacbridge/bridge.h index 8f414d9..bd01c30 100644 --- a/native/libmacbridge/bridge.h +++ b/native/libmacbridge/bridge.h @@ -37,6 +37,11 @@ int32_t initialize(void * context, const char * icon_path); */ int32_t eventloop(); +/* + * Initialize the application and start the headless eventloop, used for the espanso detect command + */ +int32_t headless_eventloop(); + /* * Called when a new keypress is made, the first argument is an char array, * while the second is the size of the array. diff --git a/native/libmacbridge/bridge.mm b/native/libmacbridge/bridge.mm index 361bfa3..d5ea434 100644 --- a/native/libmacbridge/bridge.mm +++ b/native/libmacbridge/bridge.mm @@ -64,6 +64,12 @@ int32_t eventloop() { [NSApp run]; } +int32_t headless_eventloop() { + NSApplication * application = [NSApplication sharedApplication]; + [NSApp run]; + return 0; +} + void send_string(const char * string) { char * stringCopy = strdup(string); dispatch_async(dispatch_get_main_queue(), ^(void) { diff --git a/src/bridge/macos.rs b/src/bridge/macos.rs index 830e994..40f2ee8 100644 --- a/src/bridge/macos.rs +++ b/src/bridge/macos.rs @@ -31,6 +31,7 @@ pub struct MacMenuItem { extern { pub fn initialize(s: *const c_void, icon_path: *const c_char); pub fn eventloop(); + pub fn headless_eventloop(); // System pub fn check_accessibility() -> i32; diff --git a/src/main.rs b/src/main.rs index 6718ee7..566b8a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -530,6 +530,7 @@ fn restart_main(config_set: ConfigSet) { /// Cli tool used to analyze active windows to extract useful information /// to create configuration filters. +#[cfg(not(target_os = "macos"))] fn detect_main() { let system_manager = system::get_manager(); @@ -562,6 +563,52 @@ fn detect_main() { } } +/// Cli tool used to analyze active windows to extract useful information +/// to create configuration filters. +/// On macOS version we need to start an event loop for the app to register changes. +#[cfg(target_os = "macos")] +fn detect_main() { + thread::spawn(|| { + use std::io::Write; + use std::io::stdout; + + let system_manager = system::get_manager(); + + println!("Listening for changes, now focus the window you want to analyze."); + println!("Warning: stay on the window for a few seconds, as it may take a while to register."); + println!("You can terminate with CTRL+C\n"); + + let mut last_title : String = "".to_owned(); + let mut last_class : String = "".to_owned(); + let mut last_exec : String = "".to_owned(); + + loop { + let curr_title = system_manager.get_current_window_title().unwrap_or_default(); + let curr_class = system_manager.get_current_window_class().unwrap_or_default(); + let curr_exec = system_manager.get_current_window_executable().unwrap_or_default(); + + // Check if a change occurred + if curr_title != last_title || curr_class != last_class || curr_exec != last_exec { + println!("Detected change, current window has properties:"); + println!("==> Title: '{}'", curr_title); + println!("==> Class: '{}'", curr_class); + println!("==> Executable: '{}'", curr_exec); + println!(); + } + + last_title = curr_title; + last_class = curr_class; + last_exec = curr_exec; + + thread::sleep(Duration::from_millis(500)); + } + }); + + unsafe { + crate::bridge::macos::headless_eventloop(); + } +} + /// Send the given command to the espanso daemon fn cmd_main(config_set: ConfigSet, matches: &ArgMatches) { let command = if matches.subcommand_matches("exit").is_some() {