From 0913dbf5b7ba43179e6938206e59a6969402e96d Mon Sep 17 00:00:00 2001 From: James Brunton Date: Tue, 11 Nov 2025 14:16:44 +0000 Subject: [PATCH] Fix Rust warnings (#4872) # Description of Changes Fix warnings in Rust code on Mac. They were all being caused by file handling logic which is now built into Tauri, so I've just been able to remove all of the Mac specific file handling code. I've also set warnings to be treated as errors because it'll be really easy to accidentally introudce warnings on individual platforms which I'm not developing, and I'd like to know about them so we can fix it before getting dodgy code. --- frontend/src-tauri/Cargo.lock | 87 +---------- frontend/src-tauri/Cargo.toml | 9 +- frontend/src-tauri/src/commands/files.rs | 1 + frontend/src-tauri/src/commands/mod.rs | 4 +- frontend/src-tauri/src/file_handler.rs | 189 ----------------------- frontend/src-tauri/src/lib.rs | 18 +-- 6 files changed, 17 insertions(+), 291 deletions(-) delete mode 100644 frontend/src-tauri/src/file_handler.rs 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(()) })