From 8c9ef73b550893a240c6de1a80592993a15e9766 Mon Sep 17 00:00:00 2001 From: Connor Yoh Date: Thu, 17 Jul 2025 15:01:11 +0100 Subject: [PATCH] Use proper delagate --- frontend/src-tauri/src/file_handler.rs | 74 +++++++++++++++++--------- frontend/src-tauri/src/lib.rs | 16 +++++- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/frontend/src-tauri/src/file_handler.rs b/frontend/src-tauri/src/file_handler.rs index 05ddc4df0..f01d34374 100644 --- a/frontend/src-tauri/src/file_handler.rs +++ b/frontend/src-tauri/src/file_handler.rs @@ -85,31 +85,40 @@ mod macos_native { static LAUNCH_FILES: Lazy>> = Lazy::new(|| Mutex::new(Vec::new())); - extern "C" fn open_file(_self: &Object, _cmd: Sel, _sender: id, filename: id) -> bool { + extern "C" fn open_files(_self: &Object, _cmd: Sel, _sender: id, filenames: id) { unsafe { - let cstr = { - let bytes: *const std::os::raw::c_char = msg_send![filename, UTF8String]; - std::ffi::CStr::from_ptr(bytes) - }; - if let Ok(path) = cstr.to_str() { - add_log(format!("📂 macOS native file open event: {}", path)); - if path.ends_with(".pdf") { - // Always set the opened file for command-line interface - set_opened_file(path.to_string()); - - if let Some(app) = APP_HANDLE.lock().unwrap().as_ref() { - // App is running, emit event immediately - add_log(format!("✅ App running, emitting file event: {}", path)); - let _ = app.emit("macos://open-file", path.to_string()); - } else { - // App not ready yet, store for later processing - add_log(format!("🚀 App not ready, storing file for later: {}", path)); - LAUNCH_FILES.lock().unwrap().push(path.to_string()); + add_log(format!("📂 macOS native openFiles event called")); + + // filenames is an NSArray of NSString objects + let count: usize = msg_send![filenames, count]; + add_log(format!("📂 Number of files to open: {}", count)); + + for i in 0..count { + let filename: id = msg_send![filenames, objectAtIndex:i]; + let cstr = { + let bytes: *const std::os::raw::c_char = msg_send![filename, UTF8String]; + std::ffi::CStr::from_ptr(bytes) + }; + + if let Ok(path) = cstr.to_str() { + add_log(format!("📂 macOS file open: {}", path)); + if path.ends_with(".pdf") { + // Always set the opened file for command-line interface + set_opened_file(path.to_string()); + + if let Some(app) = APP_HANDLE.lock().unwrap().as_ref() { + // App is running, emit event immediately + add_log(format!("✅ App running, emitting file event: {}", path)); + let _ = app.emit("macos://open-file", path.to_string()); + } else { + // App not ready yet, store for later processing + add_log(format!("🚀 App not ready, storing file for later: {}", path)); + LAUNCH_FILES.lock().unwrap().push(path.to_string()); + } } } } } - true } // Register the delegate immediately when the module loads @@ -117,21 +126,38 @@ mod macos_native { add_log("🔧 Registering macOS delegate early...".to_string()); unsafe { + let ns_app = NSApplication::sharedApplication(nil); + + // Check if there's already a delegate + let existing_delegate: id = msg_send![ns_app, delegate]; + if existing_delegate != nil { + add_log("⚠️ Tauri already has an NSApplication delegate, trying to extend it...".to_string()); + + // Try to add our method to the existing delegate's class + let delegate_class = msg_send![existing_delegate, class]; + let class_name: *const std::os::raw::c_char = msg_send![delegate_class, name]; + let class_name_str = std::ffi::CStr::from_ptr(class_name).to_string_lossy(); + add_log(format!("🔍 Existing delegate class: {}", class_name_str)); + + // This approach won't work with existing classes, so let's try a different method + // We'll use method swizzling or create a new delegate that forwards to the old one + add_log("🔄 Will try alternative approach...".to_string()); + } + let delegate_class = Class::get("StirlingAppDelegate").unwrap_or_else(|| { let superclass = class!(NSObject); let mut decl = objc::declare::ClassDecl::new("StirlingAppDelegate", superclass).unwrap(); - // Add file opening delegate method + // Add file opening delegate method (modern plural version) decl.add_method( - sel!(application:openFile:), - open_file as extern "C" fn(&Object, Sel, id, id) -> bool + sel!(application:openFiles:), + open_files as extern "C" fn(&Object, Sel, id, id) ); decl.register() }); let delegate: id = msg_send![delegate_class, new]; - let ns_app = NSApplication::sharedApplication(nil); let _: () = msg_send![ns_app, setDelegate:delegate]; } diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index 249043540..ec6896036 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -4,7 +4,7 @@ mod utils; mod commands; mod file_handler; -use commands::{start_backend, check_backend_health, get_opened_file, clear_opened_file, cleanup_backend}; +use commands::{start_backend, check_backend_health, get_opened_file, clear_opened_file, cleanup_backend, set_opened_file}; use utils::{add_log, get_tauri_logs}; #[cfg_attr(mobile, tauri::mobile_entry_point)] @@ -40,6 +40,20 @@ pub fn run() { cleanup_backend(); // Allow the window to close } + #[cfg(target_os = "macos")] + RunEvent::Opened { urls } => { + add_log(format!("📂 Tauri file opened event: {:?}", urls)); + for url in urls { + if url.starts_with("file://") { + let file_path = url.strip_prefix("file://").unwrap_or(&url); + if file_path.ends_with(".pdf") { + add_log(format!("📂 Processing opened PDF: {}", file_path)); + set_opened_file(file_path.to_string()); + let _ = app_handle.emit("macos://open-file", file_path.to_string()); + } + } + } + } _ => { // Only log unhandled events in debug mode to reduce noise // #[cfg(debug_assertions)]