Implement server management enhancements with window close handling

- Introduced a checkbox in the ConnectionForm to allow users to keep the server running when the app closes.
- Added a setupWindowCloseHandler function to manage server shutdown based on user preference.
- Updated App component to integrate the new window close handling logic.
- Created a reusable Checkbox component for better UI consistency.
- Modified serverStore to include state management for the new setting.
This commit is contained in:
Jamie Pine
2026-01-25 12:13:35 -08:00
parent 9b7ee21e6c
commit 7b1e2295ef
6 changed files with 172 additions and 8 deletions
+46 -1
View File
@@ -2,8 +2,9 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use std::sync::Mutex;
use tauri::{command, State, Manager};
use tauri::{command, State, Manager, WindowEvent, Emitter, Listener};
use tauri_plugin_shell::ShellExt;
use tokio::sync::mpsc;
struct ServerState {
child: Mutex<Option<tauri_plugin_shell::process::CommandChild>>,
@@ -132,6 +133,50 @@ pub fn run() {
child: Mutex::new(None),
})
.invoke_handler(tauri::generate_handler![start_server, stop_server])
.on_window_event(|window, event| {
if let WindowEvent::CloseRequested { api, .. } = event {
// Prevent automatic close
api.prevent_close();
// Emit event to frontend to check setting and stop server if needed
let app_handle = window.app_handle();
if let Err(e) = app_handle.emit("window-close-requested", ()) {
eprintln!("Failed to emit window-close-requested event: {}", e);
// If event emission fails, allow close anyway
window.close().ok();
return;
}
// Set up listener for frontend response
let window_for_close = window.clone();
let (tx, mut rx) = mpsc::unbounded_channel::<()>();
// Listen for response from frontend using window's listen method
let listener_id = window.listen("window-close-allowed", move |_| {
// Frontend has checked setting and stopped server if needed
// Signal that we can close
let _ = tx.send(());
});
// Wait for frontend response or timeout
tokio::spawn(async move {
tokio::select! {
_ = rx.recv() => {
// Frontend responded, close window
window_for_close.close().ok();
}
_ = tokio::time::sleep(tokio::time::Duration::from_secs(5)) => {
// Timeout - close anyway
eprintln!("Window close timeout, closing anyway");
window_for_close.close().ok();
}
}
// Clean up listener
window_for_close.unlisten(listener_id);
});
}
})
.setup(|_app| {
#[cfg(debug_assertions)]
{