diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index 7e905d1..6290e50 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -301,6 +301,12 @@ dependencies = [
"serde",
]
+[[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"
@@ -517,6 +523,36 @@ dependencies = [
"windows-link",
]
+[[package]]
+name = "cocoa"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c"
+dependencies = [
+ "bitflags 1.3.2",
+ "block",
+ "cocoa-foundation",
+ "core-foundation 0.9.4",
+ "core-graphics 0.23.2",
+ "foreign-types 0.5.0",
+ "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"
@@ -2185,6 +2221,15 @@ dependencies = [
"time",
]
+[[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"
@@ -2408,6 +2453,15 @@ dependencies = [
"syn 2.0.104",
]
+[[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"
@@ -3053,10 +3107,12 @@ version = "0.3.10"
dependencies = [
"base64 0.21.7",
"chrono",
+ "cocoa",
"core-foundation 0.9.4",
"core-graphics 0.23.2",
"dotenv",
"libc",
+ "objc",
"serde",
"serde_json",
"tauri",
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index d58cba0..bbed9d3 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -51,4 +51,6 @@ base64 = "0.21"
core-graphics = "0.23"
core-foundation = "0.9"
libc = "0.2"
+cocoa = "0.25"
+objc = "0.2"
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index 8481916..5ea6b19 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -87,6 +87,8 @@ struct AppSettings {
autostart: bool,
#[serde(default = "default_analytics_enabled")]
analytics_enabled: bool,
+ #[serde(default)]
+ hide_icon_on_close: bool,
}
#[derive(Serialize, Deserialize, Clone)]
@@ -174,6 +176,7 @@ impl Default for AppSettings {
advanced: AdvancedSettings::default(),
autostart: false, // default to disabled
analytics_enabled: true, // default to enabled
+ hide_icon_on_close: false, // default to disabled
}
}
}
@@ -612,6 +615,22 @@ async fn update_tray_icon(
#[tauri::command]
async fn show_window(app: AppHandle) -> Result<(), String> {
if let Some(window) = app.get_webview_window("main") {
+ // Check if hide_icon_on_close is enabled to restore dock visibility
+ match load_settings(app.clone()).await {
+ Ok(settings) => {
+ if settings.hide_icon_on_close {
+ // Restore dock visibility when showing window
+ #[cfg(target_os = "macos")]
+ {
+ let _ = set_dock_visibility(app.clone(), true).await;
+ }
+ }
+ }
+ Err(_) => {
+ // Ignore error, just proceed with showing window
+ }
+ }
+
window
.show()
.map_err(|e| format!("Failed to show window: {}", e))?;
@@ -929,7 +948,8 @@ pub fn run() {
save_session_tags,
add_session_tag,
write_excel_file,
- start_oauth_server
+ start_oauth_server,
+ set_dock_visibility
])
.setup(|app| {
// Track app started event (if enabled)
@@ -1023,9 +1043,42 @@ pub fn run() {
.build(app)?;
if let Some(window) = app.get_webview_window("main") {
+ let app_handle_for_close = app.handle().clone();
window.on_window_event(move |event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
+ // Always prevent close
api.prevent_close();
+
+ // Check if we should hide the app icon
+ let app_handle_clone = app_handle_for_close.clone();
+ tauri::async_runtime::spawn(async move {
+ match load_settings(app_handle_clone.clone()).await {
+ Ok(settings) => {
+ if settings.hide_icon_on_close {
+ // Hide the window and set app as dock hidden
+ if let Some(window) = app_handle_clone.get_webview_window("main") {
+ let _ = window.hide();
+ // Use macOS specific API to hide from dock
+ #[cfg(target_os = "macos")]
+ {
+ let _ = set_dock_visibility(app_handle_clone.clone(), false).await;
+ }
+ }
+ } else {
+ // Just hide the window without hiding from dock
+ if let Some(window) = app_handle_clone.get_webview_window("main") {
+ let _ = window.hide();
+ }
+ }
+ }
+ Err(_) => {
+ // Default behavior: just hide the window
+ if let Some(window) = app_handle_clone.get_webview_window("main") {
+ let _ = window.hide();
+ }
+ }
+ }
+ });
}
});
}
@@ -1283,3 +1336,40 @@ async fn start_oauth_server(window: tauri::Window) -> ResultSystem Integration
start
minimized to the system tray.
Hide the app icon from the dock when closing the window with X. The app will continue running in the system tray.
+