diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index c4b49a210691fa079fc621e1bcda83d044e57dad..62b75611b31faf9c945160cef24bc145d9f8d339 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -495,6 +495,7 @@ dependencies = [
  "anyhow",
  "auto-launch",
  "chrono",
+ "ctrlc",
  "deelevate",
  "delay_timer",
  "dirs 4.0.0",
@@ -757,6 +758,16 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "ctrlc"
+version = "3.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173"
+dependencies = [
+ "nix",
+ "winapi",
+]
+
 [[package]]
 name = "cty"
 version = "0.2.2"
@@ -1946,9 +1957,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.126"
+version = "0.2.132"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
 
 [[package]]
 name = "libloading"
@@ -2244,6 +2255,18 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
 
+[[package]]
+name = "nix"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb"
+dependencies = [
+ "autocfg",
+ "bitflags",
+ "cfg-if 1.0.0",
+ "libc",
+]
+
 [[package]]
 name = "nodrop"
 version = "0.1.14"
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 4dfdceaf8236da7237dcf065ca48a54d477de44a..b369b32b74a672b745b321a92b52d437f30d3193 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -19,6 +19,7 @@ anyhow = "1.0"
 dirs = "4.0.0"
 open = "2.1.1"
 log = "0.4.14"
+ctrlc = "3.2.3"
 dunce = "1.0.2"
 log4rs = "1.0.0"
 nanoid = "0.4.0"
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index a116ffbea2cdf4f2646be3f78c1401a2467c1c3f..b5e53b32e2b4aee75557b8f2802bae9fa8623528 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -14,6 +14,7 @@ use crate::{
 };
 use tauri::{
   api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
+  WindowEvent,
 };
 
 fn main() -> std::io::Result<()> {
@@ -176,19 +177,41 @@ fn main() -> std::io::Result<()> {
     builder = builder.menu(Menu::new().add_submenu(submenu_file));
   }
 
-  builder
+  let app = builder
     .build(context)
-    .expect("error while running tauri application")
-    .run(|app_handle, e| match e {
-      tauri::RunEvent::ExitRequested { api, .. } => {
-        api.prevent_exit();
-      }
-      tauri::RunEvent::Exit => {
-        resolve::resolve_reset(app_handle);
-        api::process::kill_children();
+    .expect("error while running tauri application");
+
+  let app_handle = app.app_handle();
+  ctrlc::set_handler(move || {
+    resolve::resolve_reset(&app_handle);
+    app_handle.exit(0);
+  })
+  .expect("error when exiting.");
+
+  app.run(|app_handle, e| match e {
+    tauri::RunEvent::ExitRequested { api, .. } => {
+      api.prevent_exit();
+    }
+    tauri::RunEvent::Exit => {
+      resolve::resolve_reset(app_handle);
+      api::process::kill_children();
+    }
+    #[cfg(target_os = "macos")]
+    tauri::RunEvent::WindowEvent { label, event, .. } => {
+      if label == "main" {
+        match event {
+          WindowEvent::CloseRequested { api, .. } => {
+            api.prevent_close();
+            app_handle.get_window("main").map(|win| {
+              let _ = win.hide();
+            });
+          }
+          _ => {}
+        }
       }
-      _ => {}
-    });
+    }
+    _ => {}
+  });
 
   Ok(())
 }
diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx
index dbbe2dd5f75372f987870577484f0ed1755fc23b..4361b2fc248e55f38c2aa8576fd3b6c89f19e634 100644
--- a/src/pages/_layout.tsx
+++ b/src/pages/_layout.tsx
@@ -43,7 +43,10 @@ const Layout = () => {
 
   useEffect(() => {
     window.addEventListener("keydown", (e) => {
-      if (e.key === "Escape") appWindow.close();
+      if (e.key === "Escape") {
+        if (OS === "macos") appWindow.hide();
+        else appWindow.close();
+      }
     });
 
     listen("verge://refresh-clash-config", async () => {