fix(desktop): menu stale-closure, window-close capability, deep-link surfacing#71
Merged
Merged
Conversation
…surfacing Three independent fixes ported from a downstream fork: - Grant core:window:allow-destroy in capabilities/default.json so the frontend win.destroy() in App.tsx's onCloseRequested guard is permitted by the ACL — without it, Discard/Don't-Save couldn't actually close the window (core:default bundles only read-only window commands). - Surface the main window (show/unminimize/set_focus, best-effort) after a quill://open deep link emits, so an incoming link no longer leaves the window hidden, minimized, or backgrounded. - Fix a React stale-closure bug in App.tsx's menu wiring: listeners are registered once but aliased menuHandlersRef.current at registration time, snapshotting the first render's handlers (symptom: Cmd+S always routed to Save-As). Each wired callback now dereferences the ref at fire time. Guarded by a new unit test (src/test/utils/menuHandlerRef.test.ts). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ESi6dnK3Wc1jYRpZN5qfZA
LFG Group 2 plan artifact for the three ported bug fixes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ESi6dnK3Wc1jYRpZN5qfZA
Merged
sam-powers
added a commit
that referenced
this pull request
Jul 10, 2026
Patch release bundling the fixes from PRs #70–#74: - @claude CLI resolution: working PATH + prefer configured binary (#70) - desktop: menu stale-closure, window-close capability, deep-link window surfacing (#71) - retry failed @claude replies in place (#72) - re-run cancelled @claude replies; remove broken new-session (#73) - surface @claude in composer placeholders; widen reading measure (#74) Also removes the stray docs/to-improve and docs/plans files that landed via #70 — those are downstream porting notes, not public-repo content. Claude-Session: https://claude.ai/code/session_01ESi6dnK3Wc1jYRpZN5qfZA Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three independent bug fixes ported from a downstream fork (LFG Group 2 of a multi-group port). Each is small and self-contained; they ship together because they were fixed together upstream.
1. Window won't close from the unsaved-changes dialog (capability grant)
App.tsx'sonCloseRequestedguard already callswin.destroy()on the Discard/Don't-Save path, but the Tauri ACL never granted it —core:defaultbundles only read-only window commands (core:window:default), sodestroywas blocked in the built app. Addedcore:window:allow-destroytocapabilities/default.json(scoped towindows: ["main"], minimal grant). No App.tsx change needed — the frontend side was already correct.2. Deep link opens a doc but leaves the window hidden (Rust)
In
lib.rs'son_open_urlclosure, after emittingdeep-link-openwe now best-effortshow()/unminimize()/set_focus()the"main"window (Results ignored), so aquill://open?file=…link surfaces the app when it's running hidden, minimized, or backgrounded. Additive; the cold-startPendingDeepLinkbuffering path is untouched (it surfaces via normal startup).3.
Cmd+Sand other native-menu shortcuts fired stale handlers (frontend — the real bug)The menu-event
useEffectregisters listeners once, but it aliasedconst h = menuHandlersRef.currentat registration time, snapshotting the first render's handlers. Symptom:Cmd+Salways routed to Save-As becausehandleSaveclosed over the initialopenFilePath = null. Each wired callback now dereferencesmenuHandlersRef.currentat fire time, matching the pattern the neighboring Open-Recent handler already used. Covered by a new unit test,src/test/utils/menuHandlerRef.test.ts, which fails red against a registration-time-alias revert.Testing
npm run typecheck,npm run lint,npm run format:check— cleannpx vitest run— 258/258 (incl. 3 new menu-handler-ref tests)cargo fmt --check,cargo clippy -- -D warnings,cargo test— clean (35 Rust unit tests, incl. thedeep_link_*suite)Manual verification (out of automated scope by design): #1 (ACL destroy grant) and #2 (deep-link window surfacing) require a built
.appand the native Tauri IPC/deep-link runtime — verified manually in a packaged build. #3 is unit-tested.🤖 Generated with Claude Code