diff --git a/frontend/src-tauri/Cargo.lock b/frontend/src-tauri/Cargo.lock index 5f4f9b350..84cd44f02 100644 --- a/frontend/src-tauri/Cargo.lock +++ b/frontend/src-tauri/Cargo.lock @@ -155,12 +155,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-buffer" version = "0.10.4" @@ -420,36 +414,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "cocoa" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation 0.9.4", - "core-graphics 0.22.3", - "foreign-types 0.3.2", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "libc", - "objc", -] - [[package]] name = "combine" version = "4.6.7" @@ -502,19 +466,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "foreign-types 0.3.2", - "libc", -] - [[package]] name = "core-graphics" version = "0.24.0" @@ -523,22 +474,11 @@ checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ "bitflags 2.10.0", "core-foundation 0.10.1", - "core-graphics-types 0.2.0", + "core-graphics-types", "foreign-types 0.5.0", "libc", ] -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - [[package]] name = "core-graphics-types" version = "0.2.0" @@ -1992,15 +1932,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "markup5ever" version = "0.14.1" @@ -2200,15 +2131,6 @@ dependencies = [ "libc", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "objc-sys" version = "0.3.5" @@ -3689,7 +3611,7 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" dependencies = [ "bytemuck", "cfg_aliases", - "core-graphics 0.24.0", + "core-graphics", "foreign-types 0.5.0", "js-sys", "log", @@ -3739,10 +3661,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" name = "stirling-pdf" version = "0.1.0" dependencies = [ - "cocoa", "log", - "objc", - "once_cell", "reqwest 0.11.27", "serde", "serde_json", @@ -3887,7 +3806,7 @@ dependencies = [ "bitflags 2.10.0", "block2 0.6.2", "core-foundation 0.10.1", - "core-graphics 0.24.0", + "core-graphics", "crossbeam-channel", "dispatch", "dlopen2", diff --git a/frontend/src-tauri/Cargo.toml b/frontend/src-tauri/Cargo.toml index caddf867d..0ba9b7886 100644 --- a/frontend/src-tauri/Cargo.toml +++ b/frontend/src-tauri/Cargo.toml @@ -10,6 +10,9 @@ rust-version = "1.77.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lints.rust] +warnings = "deny" + [lib] name = "app_lib" crate-type = ["staticlib", "cdylib", "rlib"] @@ -27,9 +30,3 @@ tauri-plugin-shell = "2.1.0" tauri-plugin-fs = "2.4.4" tokio = { version = "1.0", features = ["time"] } reqwest = { version = "0.11", features = ["json"] } - -# macOS-specific dependencies for native file opening -[target.'cfg(target_os = "macos")'.dependencies] -objc = "0.2" -cocoa = "0.24" -once_cell = "1.19" diff --git a/frontend/src-tauri/src/commands/files.rs b/frontend/src-tauri/src/commands/files.rs index 7c397cfcf..4b1cd2ad7 100644 --- a/frontend/src-tauri/src/commands/files.rs +++ b/frontend/src-tauri/src/commands/files.rs @@ -5,6 +5,7 @@ use std::sync::Mutex; static OPENED_FILE: Mutex> = Mutex::new(None); // Set the opened file path (called by macOS file open events) +#[cfg(target_os = "macos")] pub fn set_opened_file(file_path: String) { let mut opened_file = OPENED_FILE.lock().unwrap(); *opened_file = Some(file_path.clone()); diff --git a/frontend/src-tauri/src/commands/mod.rs b/frontend/src-tauri/src/commands/mod.rs index 773f5d2dd..3f4ed7ecd 100644 --- a/frontend/src-tauri/src/commands/mod.rs +++ b/frontend/src-tauri/src/commands/mod.rs @@ -4,4 +4,6 @@ pub mod files; pub use backend::{start_backend, cleanup_backend}; pub use health::check_backend_health; -pub use files::{get_opened_file, clear_opened_file, set_opened_file}; \ No newline at end of file +pub use files::{get_opened_file, clear_opened_file}; +#[cfg(target_os = "macos")] +pub use files::set_opened_file; diff --git a/frontend/src-tauri/src/file_handler.rs b/frontend/src-tauri/src/file_handler.rs deleted file mode 100644 index d432a8131..000000000 --- a/frontend/src-tauri/src/file_handler.rs +++ /dev/null @@ -1,189 +0,0 @@ -/// Multi-platform file opening handler -/// -/// This module provides unified file opening support across platforms: -/// - macOS: Uses native NSApplication delegate (proper Apple Events) -/// - Windows/Linux: Uses command line arguments (fallback approach) -/// - All platforms: Runtime event handling via Tauri events - -use crate::utils::add_log; -use crate::commands::set_opened_file; -use tauri::AppHandle; - - -/// Initialize file handling for the current platform -pub fn initialize_file_handler(app: &AppHandle) { - add_log("🔧 Initializing file handler...".to_string()); - - // Platform-specific initialization - #[cfg(target_os = "macos")] - { - add_log("🍎 Using macOS native file handler".to_string()); - macos_native::register_open_file_handler(app); - } - - #[cfg(not(target_os = "macos"))] - { - add_log("🖥️ Using command line argument file handler".to_string()); - let _ = app; // Suppress unused variable warning - } - - // Universal: Check command line arguments (works on all platforms) - check_command_line_args(); -} - -/// Early initialization for macOS delegate registration -pub fn early_init() { - #[cfg(target_os = "macos")] - { - add_log("🔄 Early macOS initialization...".to_string()); - macos_native::register_delegate_early(); - } -} - -/// Check command line arguments for file paths (universal fallback) -fn check_command_line_args() { - let args: Vec = std::env::args().collect(); - add_log(format!("🔍 DEBUG: All command line args: {:?}", args)); - - // Check command line arguments for file opening - for (i, arg) in args.iter().enumerate() { - add_log(format!("🔍 DEBUG: Arg {}: {}", i, arg)); - if i > 0 && arg.ends_with(".pdf") && std::path::Path::new(arg).exists() { - add_log(format!("📂 File argument detected: {}", arg)); - set_opened_file(arg.clone()); - break; // Only handle the first PDF file - } - } -} - -/// Handle runtime file open events (for future single-instance support) -#[allow(dead_code)] -pub fn handle_runtime_file_open(file_path: String) { - if file_path.ends_with(".pdf") && std::path::Path::new(&file_path).exists() { - add_log(format!("📂 Runtime file open: {}", file_path)); - set_opened_file(file_path); - } -} - -#[cfg(target_os = "macos")] -mod macos_native { - use objc::{class, msg_send, sel, sel_impl}; - use objc::runtime::{Class, Object, Sel}; - use cocoa::appkit::NSApplication; - use cocoa::base::{id, nil}; - use once_cell::sync::Lazy; - use std::sync::Mutex; - use tauri::{AppHandle, Emitter}; - - use crate::utils::add_log; - use crate::commands::set_opened_file; - - // Static app handle storage - static APP_HANDLE: Lazy>>> = Lazy::new(|| Mutex::new(None)); - - // Store files opened during launch - static LAUNCH_FILES: Lazy>> = Lazy::new(|| Mutex::new(Vec::new())); - - - extern "C" fn open_files(_self: &Object, _cmd: Sel, _sender: id, filenames: id) { - unsafe { - 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()); - } - } - } - } - } - } - - // Register the delegate immediately when the module loads - pub fn register_delegate_early() { - 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: id = 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 (modern plural version) - decl.add_method( - sel!(application:openFiles:), - open_files as extern "C" fn(&Object, Sel, id, id) - ); - - decl.register() - }); - - let delegate: id = msg_send![delegate_class, new]; - let _: () = msg_send![ns_app, setDelegate:delegate]; - } - - add_log("✅ macOS delegate registered early".to_string()); - } - - pub fn register_open_file_handler(app: &AppHandle) { - add_log("🔧 Connecting app handle to file handler...".to_string()); - - // Store the app handle - *APP_HANDLE.lock().unwrap() = Some(app.clone()); - - // Process any files that were opened during launch - let launch_files = { - let mut files = LAUNCH_FILES.lock().unwrap(); - let result = files.clone(); - files.clear(); - result - }; - - for file_path in launch_files { - add_log(format!("📂 Processing stored launch file: {}", file_path)); - set_opened_file(file_path.clone()); - let _ = app.emit("macos://open-file", file_path); - } - - add_log("✅ macOS file handler connected successfully".to_string()); - } -} \ No newline at end of file diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index f64b8bd0b..9045e1e6d 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -1,26 +1,22 @@ -use tauri::{RunEvent, WindowEvent, Emitter}; +use tauri::{RunEvent, WindowEvent}; +#[cfg(target_os = "macos")] +use tauri::Emitter; mod utils; mod commands; -mod file_handler; -use commands::{start_backend, check_backend_health, get_opened_file, clear_opened_file, cleanup_backend, set_opened_file}; +use commands::{start_backend, check_backend_health, get_opened_file, clear_opened_file, cleanup_backend}; +#[cfg(target_os = "macos")] +use commands::set_opened_file; use utils::{add_log, get_tauri_logs}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { - // Initialize file handler early for macOS - file_handler::early_init(); - tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_fs::init()) - .setup(|app| { + .setup(|_app| { add_log("🚀 Tauri app setup started".to_string()); - - // Initialize platform-specific file handler - file_handler::initialize_file_handler(&app.handle()); - add_log("🔍 DEBUG: Setup completed".to_string()); Ok(()) })