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.
This commit is contained in:
Claude 2025-11-12 00:20:11 +00:00
parent ac353bb5a6
commit 9a4c48d9ea
No known key found for this signature in database

17
main.js
View File

@ -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==`, 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}`); log = (message) => console.log(`${LOG_PREFIX}: ${message}`);
let tray, plugin; let tray, plugin, isQuitting = false;
const obsidian = require("obsidian"), const obsidian = require("obsidian"),
{ app, Tray, Menu } = require("electron").remote, { app, Tray, Menu } = require("electron").remote,
{ nativeImage, BrowserWindow } = require("electron").remote, { nativeImage, BrowserWindow } = require("electron").remote,
@ -97,8 +97,14 @@ const vaultWindows = new Set(),
else showWindows(); 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) => { onWindowUnload = (event) => {
// allow window to close during app quit
if (isQuitting) return;
log(LOG_WINDOW_CLOSE); log(LOG_WINDOW_CLOSE);
getCurrentWindow().hide(); getCurrentWindow().hide();
event.stopImmediatePropagation(); event.stopImmediatePropagation();
@ -113,6 +119,13 @@ const onWindowClose = (event) => event.preventDefault(),
// from renderer, so won't prevent close by itself, but counteracts // from renderer, so won't prevent close by itself, but counteracts
// the 3-second delayed window force close in obsidian.asar/main.js // the 3-second delayed window force close in obsidian.asar/main.js
getCurrentWindow().on("close", onWindowClose); 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 = () => { allowWindowClose = () => {
getCurrentWindow().removeListener("close", onWindowClose); getCurrentWindow().removeListener("close", onWindowClose);