Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changeset/window-close.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Bug Fixes
- Closing the window quits Stroke again. 2.1.0 dropped the tray and the hide-on-close handler that went with it, which let close run through to `destroy` for the first time. `destroy` was never in the capability file, so the ACL refused it and the window stayed put. With no tray and no window decorations, that left no way to quit the app at all.
- Second windows (`Ctrl/Cmd+Shift+N`) respond to their title bar again. The capability only covered the window labelled `main`, so every control on a second window (close, minimize, maximize, and dragging the bar) was denied.
4 changes: 3 additions & 1 deletion src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
"main",
"main-*"
],
"permissions": [
"core:default",
Expand All @@ -24,6 +25,7 @@
"core:window:allow-set-fullscreen",
"core:window:allow-is-fullscreen",
"core:window:allow-close",
"core:window:allow-destroy",
"core:window:allow-minimize",
"core:window:allow-maximize",
"core:window:allow-unmaximize",
Expand Down
29 changes: 18 additions & 11 deletions src/lib/components/WindowControls.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,26 @@
return () => unlisten()
})

async function minimizeWindow() {
const { getCurrentWindow } = await import('@tauri-apps/api/window')
getCurrentWindow().minimize()
}
async function toggleMaximizeWindow() {
const { getCurrentWindow } = await import('@tauri-apps/api/window')
getCurrentWindow().toggleMaximize()
}
async function closeWindow() {
const { getCurrentWindow } = await import('@tauri-apps/api/window')
getCurrentWindow().close()
// Every one of these is an ACL-gated core command, and the window is frameless,
// so these buttons are the only chrome there is - a denied call leaves the user
// with a window they cannot move, resize or close. That is how the missing
// `core:window:allow-destroy` shipped in 2.1.0: `close()` runs through to
// `destroy`, the ACL refused it, and the rejection went nowhere. Await and log
// so the next gap in src-tauri/capabilities/default.json is visible.
/** @param {string} name @param {(w: import('@tauri-apps/api/window').Window) => Promise<unknown>} fn */
async function windowAction(name, fn) {
try {
const { getCurrentWindow } = await import('@tauri-apps/api/window')
await fn(getCurrentWindow())
} catch (err) {
console.error(`window ${name} failed:`, err)
}
}

const minimizeWindow = () => windowAction('minimize', (w) => w.minimize())
const toggleMaximizeWindow = () => windowAction('toggleMaximize', (w) => w.toggleMaximize())
const closeWindow = () => windowAction('close', (w) => w.close())

const winBtn = 'inline-flex size-6 items-center justify-center rounded-md text-muted-foreground transition-colors duration-150 hover:bg-foreground/[0.08] hover:text-foreground'
</script>

Expand Down
Loading