Skip to content

fix(desktop): menu stale-closure, window-close capability, deep-link surfacing#71

Merged
sam-powers merged 2 commits into
mainfrom
fix/menu-stale-closure-window-surfacing
Jul 10, 2026
Merged

fix(desktop): menu stale-closure, window-close capability, deep-link surfacing#71
sam-powers merged 2 commits into
mainfrom
fix/menu-stale-closure-window-surfacing

Conversation

@sam-powers

Copy link
Copy Markdown
Owner

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's onCloseRequested guard already calls win.destroy() on the Discard/Don't-Save path, but the Tauri ACL never granted it — core:default bundles only read-only window commands (core:window:default), so destroy was blocked in the built app. Added core:window:allow-destroy to capabilities/default.json (scoped to windows: ["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's on_open_url closure, after emitting deep-link-open we now best-effort show() / unminimize() / set_focus() the "main" window (Results ignored), so a quill://open?file=… link surfaces the app when it's running hidden, minimized, or backgrounded. Additive; the cold-start PendingDeepLink buffering path is untouched (it surfaces via normal startup).

3. Cmd+S and other native-menu shortcuts fired stale handlers (frontend — the real bug)

The menu-event useEffect registers listeners once, but it aliased const h = menuHandlersRef.current at registration time, snapshotting the first render's handlers. Symptom: Cmd+S always routed to Save-As because handleSave closed over the initial openFilePath = null. Each wired callback now dereferences menuHandlersRef.current at 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 — clean
  • npx vitest run258/258 (incl. 3 new menu-handler-ref tests)
  • cargo fmt --check, cargo clippy -- -D warnings, cargo test — clean (35 Rust unit tests, incl. the deep_link_* suite)

Manual verification (out of automated scope by design): #1 (ACL destroy grant) and #2 (deep-link window surfacing) require a built .app and the native Tauri IPC/deep-link runtime — verified manually in a packaged build. #3 is unit-tested.

🤖 Generated with Claude Code

sam-powers and others added 2 commits July 9, 2026 07:32
…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
@sam-powers
sam-powers merged commit 9cee0e5 into main Jul 10, 2026
3 checks passed
@sam-powers
sam-powers deleted the fix/menu-stale-closure-window-surfacing branch July 10, 2026 12:42
@sam-powers sam-powers mentioned this pull request Jul 10, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant