diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json
index f8363c3..a7a7827 100644
--- a/src-tauri/capabilities/default.json
+++ b/src-tauri/capabilities/default.json
@@ -30,6 +30,7 @@
},
"core:window:allow-set-size",
"core:window:allow-set-always-on-top",
- "core:window:allow-inner-size"
+ "core:window:allow-inner-size",
+ "core:window:allow-hide"
]
}
diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs
index 1be5ccd..69c418c 100644
--- a/src-tauri/src/commands.rs
+++ b/src-tauri/src/commands.rs
@@ -1154,6 +1154,19 @@ pub async fn log_discord_rpc(
Ok(())
}
+#[tauri::command]
+pub async fn close_application(app_handle: AppHandle) -> Result<(), String> {
+ // Get the main window
+ if let Some(window) = app_handle.get_webview_window("main") {
+ // Hide the window first for a smoother close
+ let _ = window.hide();
+ }
+
+ // Exit the application
+ app_handle.exit(0);
+ Ok(())
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs
index b8fe217..f66086b 100644
--- a/src-tauri/src/config.rs
+++ b/src-tauri/src/config.rs
@@ -71,9 +71,6 @@ pub struct HikariConfig {
#[serde(default = "default_font_size")]
pub font_size: u32,
- #[serde(default)]
- pub minimize_to_tray: bool,
-
#[serde(default)]
pub streamer_mode: bool,
@@ -134,7 +131,6 @@ impl Default for HikariConfig {
update_checks_enabled: true,
character_panel_width: None,
font_size: 14,
- minimize_to_tray: false,
streamer_mode: false,
streamer_hide_paths: false,
compact_mode: false,
@@ -242,7 +238,6 @@ mod tests {
assert!(config.update_checks_enabled);
assert!(config.character_panel_width.is_none());
assert_eq!(config.font_size, 14);
- assert!(!config.minimize_to_tray);
assert!(!config.streamer_mode);
assert!(!config.streamer_hide_paths);
assert!(!config.compact_mode);
@@ -275,7 +270,6 @@ mod tests {
update_checks_enabled: true,
character_panel_width: Some(400),
font_size: 16,
- minimize_to_tray: true,
streamer_mode: false,
streamer_hide_paths: false,
compact_mode: false,
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index 3fe20e9..d9a0a9d 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -33,11 +33,11 @@ use quick_actions::*;
use sessions::*;
use snippets::*;
use std::sync::Arc;
-use tauri::Manager;
+use tauri::{Emitter, Manager};
use temp_manager::create_shared_temp_manager;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
-use tray::{setup_tray, should_minimize_to_tray};
+use tray::setup_tray;
use vbs_notification::*;
use windows_toast::*;
use wsl_notifications::*;
@@ -89,17 +89,18 @@ pub fn run() {
eprintln!("Failed to set up system tray: {}", e);
}
- // Handle window close event for minimize to tray
+ // Handle window close event for minimize to tray and close confirmation
let main_window = app.get_webview_window("main").unwrap();
main_window.on_window_event({
let app_handle = app.handle().clone();
move |event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
- if should_minimize_to_tray(&app_handle) {
- api.prevent_close();
- if let Some(window) = app_handle.get_webview_window("main") {
- let _ = window.hide();
- }
+ // Always prevent default close - let frontend handle it
+ api.prevent_close();
+
+ // Emit event to frontend to show confirmation modal
+ if let Some(window) = app_handle.get_webview_window("main") {
+ let _ = window.emit("window-close-requested", ());
}
}
}
@@ -194,6 +195,7 @@ pub fn run() {
update_discord_rpc,
stop_discord_rpc,
log_discord_rpc,
+ close_application,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
diff --git a/src-tauri/src/tray.rs b/src-tauri/src/tray.rs
index 9f87b0b..4532ac7 100644
--- a/src-tauri/src/tray.rs
+++ b/src-tauri/src/tray.rs
@@ -4,8 +4,6 @@ use tauri::{
AppHandle, Manager,
};
-use crate::config::HikariConfig;
-
pub fn setup_tray(app: &AppHandle) -> tauri::Result<()> {
let show_item = MenuItem::with_id(app, "show", "Show Hikari", true, None::<&str>)?;
let quit_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
@@ -48,21 +46,3 @@ pub fn setup_tray(app: &AppHandle) -> tauri::Result<()> {
Ok(())
}
-
-pub fn should_minimize_to_tray(app: &AppHandle) -> bool {
- let config_path = app
- .path()
- .app_config_dir()
- .ok()
- .map(|p| p.join("hikari-config.json"));
-
- if let Some(path) = config_path {
- if let Ok(content) = std::fs::read_to_string(&path) {
- if let Ok(config) = serde_json::from_str::
+ {#if hasActiveConversation}
+ You have an active conversation with Claude. Are you sure you want to close the
+ application? Your conversation history will be saved, but any in-progress tasks will
+ be interrupted.
+ {:else}
+ Are you sure you want to close the application?
+ {/if}
+
+ Close Hikari Desktop?
+
+
- Hide to tray instead of closing when you click the X button -
-