diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs new file mode 100644 index 0000000..6bf54ca --- /dev/null +++ b/src-tauri/src/main.rs @@ -0,0 +1,73 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +use std::sync::Mutex; +use tauri::{Manager, RunEvent, SystemTray, SystemTrayEvent, SystemTrayMenu, CustomMenuItem}; + +/// Handle to the moonrelay backend sidecar process. +struct BackendProcess(Mutex>>); + +fn main() { + // System tray menu + let quit = CustomMenuItem::new("quit", "Quit Moonlight Relay"); + let show = CustomMenuItem::new("show", "Show"); + let tray_menu = SystemTrayMenu::new() + .add_item(show) + .add_item(quit); + let tray = SystemTray::new().with_menu(tray_menu); + + tauri::Builder::default() + .system_tray(tray) + .on_system_tray_event(|app, event| { + match event { + SystemTrayEvent::MenuItemClick { id, .. } => { + match id.as_str() { + "quit" => std::process::exit(0), + "show" => { + if let Some(w) = app.get_window("main") { + let _ = w.show(); + let _ = w.set_focus(); + } + } + _ => {} + } + } + SystemTrayEvent::DoubleClick { .. } => { + if let Some(w) = app.get_window("main") { + let _ = w.show(); + let _ = w.set_focus(); + } + } + _ => {} + } + }) + .setup(|app| { + // Launch the Go backend sidecar + let sidecar = app.shell_scope().sidecar("moonrelay") + .expect("moonrelay sidecar not found — did you build the Go binary?"); + + let (mut _rx, child) = sidecar.spawn() + .expect("Failed to spawn moonrelay backend"); + + // Store handle so it's dropped (and killed) when app exits + app.manage(BackendProcess(Mutex::new(Some( + tauri::async_runtime::spawn(async move { + // Keep the handle alive; drop kills the process + let _child = child; + loop { + tauri::async_runtime::sleep(std::time::Duration::from_secs(3600)).await; + } + }) + )))); + + Ok(()) + }) + .build(tauri::generate_context!()) + .expect("error while building tauri application") + .run(|_app, event| { + // Keep running in tray when window is closed + if let RunEvent::ExitRequested { api, .. } = event { + api.prevent_exit(); + } + }); +}