mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-01 20:10:35 +01:00
# Description of Changes Fix #5189. Fix Mac app not being able to open files with spaces in their name, which was happening because the URL was not being decoded on input.
192 lines
6.3 KiB
Rust
192 lines
6.3 KiB
Rust
use tauri::{Manager, RunEvent, WindowEvent, Emitter};
|
|
|
|
mod utils;
|
|
mod commands;
|
|
mod state;
|
|
|
|
use commands::{
|
|
add_opened_file,
|
|
cleanup_backend,
|
|
clear_auth_token,
|
|
clear_opened_files,
|
|
clear_user_info,
|
|
is_default_pdf_handler,
|
|
get_auth_token,
|
|
get_backend_port,
|
|
get_connection_config,
|
|
get_opened_files,
|
|
get_user_info,
|
|
is_first_launch,
|
|
login,
|
|
reset_setup_completion,
|
|
save_auth_token,
|
|
save_user_info,
|
|
set_connection_mode,
|
|
set_as_default_pdf_handler,
|
|
start_backend,
|
|
start_oauth_login,
|
|
};
|
|
use state::connection_state::AppConnectionState;
|
|
use utils::{add_log, get_tauri_logs};
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
tauri::Builder::default()
|
|
.plugin(
|
|
tauri_plugin_log::Builder::new()
|
|
.level(log::LevelFilter::Info)
|
|
.build()
|
|
)
|
|
.plugin(tauri_plugin_opener::init())
|
|
.plugin(tauri_plugin_shell::init())
|
|
.plugin(tauri_plugin_fs::init())
|
|
.plugin(tauri_plugin_http::init())
|
|
.plugin(tauri_plugin_store::Builder::new().build())
|
|
.manage(AppConnectionState::default())
|
|
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
|
// This callback runs when a second instance tries to start
|
|
add_log(format!("📂 Second instance detected with args: {:?}", args));
|
|
|
|
// Scan args for PDF files (skip first arg which is the executable)
|
|
for arg in args.iter().skip(1) {
|
|
if std::path::Path::new(arg).exists() {
|
|
add_log(format!("📂 Forwarding file to existing instance: {}", arg));
|
|
|
|
// Store file for later retrieval (in case frontend isn't ready yet)
|
|
add_opened_file(arg.clone());
|
|
|
|
// Bring the existing window to front
|
|
if let Some(window) = app.get_webview_window("main") {
|
|
let _ = window.set_focus();
|
|
let _ = window.unminimize();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Emit a generic notification that files were added (frontend will re-read storage)
|
|
let _ = app.emit("files-changed", ());
|
|
}))
|
|
.setup(|app| {
|
|
add_log("🚀 Tauri app setup started".to_string());
|
|
|
|
// Process command line arguments on first launch
|
|
let args: Vec<String> = std::env::args().collect();
|
|
for arg in args.iter().skip(1) {
|
|
if std::path::Path::new(arg).exists() {
|
|
add_log(format!("📂 Initial file from command line: {}", arg));
|
|
add_opened_file(arg.clone());
|
|
}
|
|
}
|
|
|
|
// Start backend immediately, non-blocking
|
|
let app_handle = app.handle().clone();
|
|
|
|
tauri::async_runtime::spawn(async move {
|
|
add_log("🚀 Starting bundled backend in background".to_string());
|
|
let connection_state = app_handle.state::<AppConnectionState>();
|
|
if let Err(e) = commands::backend::start_backend(app_handle.clone(), connection_state).await {
|
|
add_log(format!("⚠️ Backend start failed: {}", e));
|
|
}
|
|
});
|
|
|
|
add_log("🔍 DEBUG: Setup completed".to_string());
|
|
Ok(())
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
start_backend,
|
|
get_backend_port,
|
|
get_opened_files,
|
|
clear_opened_files,
|
|
get_tauri_logs,
|
|
get_connection_config,
|
|
set_connection_mode,
|
|
is_default_pdf_handler,
|
|
set_as_default_pdf_handler,
|
|
is_first_launch,
|
|
reset_setup_completion,
|
|
login,
|
|
save_auth_token,
|
|
get_auth_token,
|
|
clear_auth_token,
|
|
save_user_info,
|
|
get_user_info,
|
|
clear_user_info,
|
|
start_oauth_login,
|
|
])
|
|
.build(tauri::generate_context!())
|
|
.expect("error while building tauri application")
|
|
.run(|app_handle, event| {
|
|
match event {
|
|
RunEvent::ExitRequested { .. } => {
|
|
add_log("🔄 App exit requested, cleaning up...".to_string());
|
|
cleanup_backend();
|
|
// Use Tauri's built-in cleanup
|
|
app_handle.cleanup_before_exit();
|
|
}
|
|
RunEvent::WindowEvent { event: WindowEvent::CloseRequested {.. }, .. } => {
|
|
add_log("🔄 Window close requested, cleaning up...".to_string());
|
|
cleanup_backend();
|
|
// Allow the window to close
|
|
}
|
|
RunEvent::WindowEvent { event: WindowEvent::DragDrop(drag_drop_event), .. } => {
|
|
use tauri::DragDropEvent;
|
|
match drag_drop_event {
|
|
DragDropEvent::Drop { paths, .. } => {
|
|
add_log(format!("📂 Files dropped: {:?}", paths));
|
|
let mut added_files = false;
|
|
|
|
for path in paths {
|
|
if let Some(path_str) = path.to_str() {
|
|
add_log(format!("📂 Processing dropped file: {}", path_str));
|
|
add_opened_file(path_str.to_string());
|
|
added_files = true;
|
|
}
|
|
}
|
|
|
|
if added_files {
|
|
let _ = app_handle.emit("files-changed", ());
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
#[cfg(target_os = "macos")]
|
|
RunEvent::Opened { urls } => {
|
|
use urlencoding::decode;
|
|
|
|
add_log(format!("📂 Tauri file opened event: {:?}", urls));
|
|
let mut added_files = false;
|
|
|
|
for url in urls {
|
|
let url_str = url.as_str();
|
|
if url_str.starts_with("file://") {
|
|
let encoded_path = url_str.strip_prefix("file://").unwrap_or(url_str);
|
|
|
|
// Decode URL-encoded characters (%20 -> space, etc.)
|
|
let file_path = match decode(encoded_path) {
|
|
Ok(decoded) => decoded.into_owned(),
|
|
Err(e) => {
|
|
add_log(format!("⚠️ Failed to decode file path: {} - {}", encoded_path, e));
|
|
encoded_path.to_string() // Fallback to encoded path
|
|
}
|
|
};
|
|
|
|
add_log(format!("📂 Processing opened file: {}", file_path));
|
|
add_opened_file(file_path);
|
|
added_files = true;
|
|
}
|
|
}
|
|
// Emit a generic notification that files were added (frontend will re-read storage)
|
|
if added_files {
|
|
let _ = app_handle.emit("files-changed", ());
|
|
}
|
|
}
|
|
_ => {
|
|
// Only log unhandled events in debug mode to reduce noise
|
|
// #[cfg(debug_assertions)]
|
|
// add_log(format!("🔍 DEBUG: Unhandled event: {:?}", event));
|
|
}
|
|
}
|
|
});
|
|
}
|