From 9a4c48d9ead12d9e500bc5ba1c4b75697ab967eb Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Nov 2025 00:20:11 +0000 Subject: [PATCH] fix: prevent macOS shutdown blocking when tray icon is active Added proper handling of app quit events to prevent blocking system shutdown on macOS. When the system initiates shutdown, the app now correctly allows windows to close instead of intercepting the close event and hiding them to the tray. Changes: - Added isQuitting flag to track app quit state - Modified onWindowClose to allow closing during quit - Modified onWindowUnload to skip interception during quit - Added before-quit event listener to set flag and cleanup This fix ensures that when users shut down their Mac, Obsidian will properly exit even when running in background with tray icon, resolving the issue where shutdown would hang waiting for the app. --- main.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index 4f38a71..88ccbe5 100644 --- a/main.js +++ b/main.js @@ -36,7 +36,7 @@ const LOG_PREFIX = "obsidian-tray", OBSIDIAN_BASE64_ICON = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHZSURBVDhPlZKxTxRBFMa/XZcF7nIG7mjxjoRCwomJxgsFdhaASqzQxFDzB1AQKgstLGxIiBQGJBpiCCGx8h+wgYaGgAWNd0dyHofeEYVwt/PmOTMZV9aDIL/s5pvZvPfN9yaL/+HR3eXcypta0m4juFbP5GHuXc9IbunDFc9db/G81/ZzhDMN7g8td47mll4R5BfHwZN4LOaA+fHa259PbUmIYzWkt3e2NZNo3/V9v1vvU6kkstk+tLW3ItUVr/m+c3N8MlkwxYqmBFcbwUQQCNOcyVzDwEAWjuPi5DhAMV/tKOYPX5hCyz8Gz1zX5SmWjBvZfmTSaRBJkGAIoxJHv+pVW2yIGNxOJ8bUVNcFEWLxuG1ia6JercTbttwQTeDwPS0kCMXiXtgk/jQrFUw7ptYSMWApF40yo/ytjHq98fdk3ayVE+cn2CxMb6ruz9qAJKFUKoWza1VJSi/n0+ffgYHdWW2gHuxXymg0gjCB0sjpmiaDnkL3RzDyzLqBUKns2ztQqUR0fk2TwSrGSf1eczqF5vsPZRCQSSAFLk6gqctgQRkc6TWRQLV2YMYQki9OoNkqzFQ9r+WOGuW5CrJbOzyAlPKr6MSGLbkcDwbf35oY/jRkt6cAfgNwowruAMz9AgAAAABJRU5ErkJggg==`, log = (message) => console.log(`${LOG_PREFIX}: ${message}`); -let tray, plugin; +let tray, plugin, isQuitting = false; const obsidian = require("obsidian"), { app, Tray, Menu } = require("electron").remote, { nativeImage, BrowserWindow } = require("electron").remote, @@ -97,8 +97,14 @@ const vaultWindows = new Set(), else showWindows(); }; -const onWindowClose = (event) => event.preventDefault(), +const onWindowClose = (event) => { + // allow window to close during app quit (e.g., system shutdown) + // to prevent blocking macOS shutdown process + if (!isQuitting) event.preventDefault(); + }, onWindowUnload = (event) => { + // allow window to close during app quit + if (isQuitting) return; log(LOG_WINDOW_CLOSE); getCurrentWindow().hide(); event.stopImmediatePropagation(); @@ -113,6 +119,13 @@ const onWindowClose = (event) => event.preventDefault(), // from renderer, so won't prevent close by itself, but counteracts // the 3-second delayed window force close in obsidian.asar/main.js getCurrentWindow().on("close", onWindowClose); + // listen for app quit events to allow proper shutdown + // especially important for macOS system shutdown + app.on("before-quit", () => { + log("preparing for app quit"); + isQuitting = true; + allowWindowClose(); + }); }, allowWindowClose = () => { getCurrentWindow().removeListener("close", onWindowClose);