diff --git a/src/main.rs b/src/main.rs index c74861e..80875cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,8 +11,9 @@ use input::{rebuild_keyboard_layout_map, INPUT_STATE}; use log::debug; use once_cell::sync::OnceCell; use platform::{ - ensure_accessibility_permission, run_event_listener, send_backspace, send_string, Handle, - KeyModifier, PressedKey, KEY_DELETE, KEY_ENTER, KEY_ESCAPE, KEY_SPACE, KEY_TAB, RAW_KEY_GLOBE, + add_app_change_callback, ensure_accessibility_permission, run_event_listener, send_backspace, + send_string, Handle, KeyModifier, PressedKey, KEY_DELETE, KEY_ENTER, KEY_ESCAPE, KEY_SPACE, + KEY_TAB, RAW_KEY_GLOBE, }; use ui::{UIDataAdapter, UPDATE_UI}; @@ -88,7 +89,6 @@ unsafe fn auto_toggle_vietnamese() { fn event_handler(handle: Handle, pressed_key: Option, modifiers: KeyModifier) -> bool { unsafe { - auto_toggle_vietnamese(); let pressed_key_code = pressed_key.and_then(|p| match p { PressedKey::Char(c) => Some(c), _ => None, @@ -207,6 +207,9 @@ fn main() { thread::spawn(|| { run_event_listener(&event_handler); }); + add_app_change_callback(|| { + unsafe { auto_toggle_vietnamese() }; + }); _ = app.launch(UIDataAdapter::new()); } } diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 18668fd..dd355b7 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -207,6 +207,13 @@ pub fn send_string(handle: Handle, string: &str) -> Result<(), ()> { Ok(()) } +pub fn add_app_change_callback(cb: F) +where + F: Fn() + Send + 'static, +{ + macos_ext::add_app_change_callback(cb); +} + pub fn run_event_listener(callback: &CallbackFn) { let current = CFRunLoop::get_current(); if let Ok(event_tap) = new_tap::CGEventTap::new( diff --git a/src/platform/macos_ext.rs b/src/platform/macos_ext.rs index c54b133..6f709d4 100644 --- a/src/platform/macos_ext.rs +++ b/src/platform/macos_ext.rs @@ -1,7 +1,7 @@ use cocoa::appkit::{ NSApp, NSApplication, NSButton, NSMenu, NSMenuItem, NSStatusBar, NSStatusItem, }; -use cocoa::base::{nil, YES}; +use cocoa::base::{id, nil, YES}; use cocoa::foundation::{NSAutoreleasePool, NSString}; use core_foundation::dictionary::CFDictionaryRef; use core_foundation::string::CFStringRef; @@ -12,10 +12,10 @@ use core_graphics::{ use druid::{Data, Lens}; use libc::c_void; use objc::{ + class, declare::ClassDecl, msg_send, - runtime::Class, - runtime::{Object, Sel}, + runtime::{Class, Object, Sel}, sel, sel_impl, Message, }; use objc_foundation::{INSObject, NSObject}; @@ -342,3 +342,26 @@ extern "C" { pub fn AXIsProcessTrustedWithOptions(options: CFDictionaryRef) -> bool; pub static kAXTrustedCheckOptionPrompt: CFStringRef; } + +#[link(name = "AppKit", kind = "framework")] +extern "C" { + pub static NSWorkspaceDidActivateApplicationNotification: CFStringRef; +} + +pub fn add_app_change_callback(cb: F) +where + F: Fn() + Send + 'static, +{ + unsafe { + let shared_workspace: id = msg_send![class!(NSWorkspace), sharedWorkspace]; + let notification_center: id = msg_send![shared_workspace, notificationCenter]; + let cb_obj = Callback::from(Box::new(cb)); + + let _: id = msg_send![notification_center, + addObserver:cb_obj + selector:sel!(call) + name:NSWorkspaceDidActivateApplicationNotification + object:nil + ]; + } +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index c0f0d74..9a3c590 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -7,9 +7,9 @@ use std::fmt::Display; use bitflags::bitflags; pub use os::{ - ensure_accessibility_permission, get_active_app_name, get_home_dir, is_in_text_selection, - is_launch_on_login, run_event_listener, send_backspace, send_string, update_launch_on_login, - Handle, SYMBOL_ALT, SYMBOL_CTRL, SYMBOL_SHIFT, SYMBOL_SUPER, + add_app_change_callback, ensure_accessibility_permission, get_active_app_name, get_home_dir, + is_in_text_selection, is_launch_on_login, run_event_listener, send_backspace, send_string, + update_launch_on_login, Handle, SYMBOL_ALT, SYMBOL_CTRL, SYMBOL_SHIFT, SYMBOL_SUPER, }; #[cfg(target_os = "macos")]