use std::ops::Deref; use objc2::rc::Id; use objc2::{declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass}; use objc2_app_kit::NSApplication; use objc2_foundation::{MainThreadMarker, NSNumber, NSObject, NSObjectProtocol}; #[derive(Clone)] pub struct AppProxy(pub Id); impl Deref for AppProxy { type Target = Id; fn deref(&self) -> &Self::Target { &self.0 } } impl types::AppProxy for AppProxy { fn wake(&self, id: i64) { use objc2_foundation::NSObjectNSThreadPerformAdditions; unsafe { self.performSelectorOnMainThread_withObject_waitUntilDone( objc2::sel!(updateInMain:), // Some(&NSNumber::new_i64(id)), false, ) }; } } declare_class!( pub struct AppProxyObj; unsafe impl ClassType for AppProxyObj { type Super = NSObject; type Mutability = mutability::Immutable; const NAME: &'static str = "XLoopAppProxy"; } impl DeclaredClass for AppProxyObj {} unsafe impl AppProxyObj { #[method(updateInMain:)] fn update_in_main(&self, val: &NSNumber){ self.update_in_main_(val) } } ); unsafe impl Send for AppProxyObj {} unsafe impl Sync for AppProxyObj {} impl AppProxyObj { pub(crate) fn new() -> Id { unsafe { msg_send_id![AppProxyObj::alloc(), init] } } fn update_in_main_(&self, val: &NSNumber) { let mtm = MainThreadMarker::new().unwrap(); let app = NSApplication::sharedApplication(mtm); let value = val.as_i64(); for win in &app.windows() { if win.respondsToSelector(sel!(updateProxy:)) { let _: () = unsafe { msg_send![win, updateProxy:value] }; } } } }