Fix hotkey not reliably summoning the palette (v0.1.15)#19
Merged
Conversation
Three fixes found while tracing 'hotkey doesn't trigger most of the time' back to real, factually-confirmed causes: - Two competing processes could run simultaneously (a stray /Applications install alongside a cargo tauri dev session), each with its own independently-cached SettingsStore and its own attempt at registering the same global hotkey — confirmed via ps aux showing both alive at once. Added tauri-plugin-single-instance so a second launch just re-summons the running instance's palette instead of starting a competing process. Verified live: launching the built binary twice leaves exactly one process alive, confirmed via ps that the second exits (defunct, status 0). - The palette runs under ActivationPolicy::Accessory (no Dock icon) — the one case where WebviewWindow::set_focus() alone is unreliable on macOS. It calls makeKeyAndOrderFront: on the window but never activates the process; summoned via a background hotkey while another app holds focus, the window could end up shown but not actually key, silently swallowing keyboard input. Confirmed via grep that this codebase never called NSApplication activateIgnoringOtherApps: anywhere. Added it to show_palette. - closingRef (lets the toggle-hotkey listener tell 'idle' apart from 'mid-close-animation') was mirrored from React state via a useEffect, which only runs after React commits — a hotkey press landing in that gap read a stale value and silently no-op'd instead of cancelling the close and reopening. Now updated synchronously at the same call site as setClosing. Bump to v0.1.15, changelog entry.
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.
Investigation
User reported the global hotkey "not triggering most of the times" after resolving an unrelated port-5173 conflict with
cargo tauri dev. Traced to three separate, factually-confirmed issues rather than assumed OS flakiness:ps auxshowed two livesupersearch-appprocesses running concurrently (a leftover/Applicationsinstall alongside the dev session). Each process loads its ownSettingsStoreonce at its own boot and independently registers the same global hotkey — two processes racing for one OS-level hotkey means summoning "the palette" nondeterministically shows either one's window.grep-confirmed absence of anyNSApplication/activateIgnoringOtherApps:call anywhere in the codebase. The palette runs underActivationPolicy::Accessory(no Dock icon) — the one case whereWebviewWindow::set_focus()alone is known-unreliable on macOS: it callsmakeKeyAndOrderFront:on the window but never activates the process. Summoned via a background hotkey while a different app holds focus, the window can end up shown but never actually key — silently swallows all keyboard input, indistinguishable from "the hotkey did nothing."closingRefread a stale value across a real timing gap. It mirroredclosingReact state via auseEffect, which only runs after React commits the next render — a hotkey re-summon landing in that gap (e.g. right afterhide_on_blurstarts a close) read the previous value and took the wrong branch, callinghide()again (a no-op) instead of cancelling the close and reopening.Fix
tauri-plugin-single-instance, registered first (Tauri's required order). A second launch now re-summons the one running instance's palette instead of starting a competing process.show_palettenow callsactivateIgnoringOtherApps:onNSApplication(via the sameobjc2FFI pattern already used forenable_fullscreen_overlay) before focusing the window.closingRefis now updated synchronously at the same call site assetClosing(via a newsetClosingBothhelper), eliminating the effect-timing gap entirely instead of narrowing it.Verification
cargo check/cargo test(17/17) clean,tsc --noEmitclean.psthat the second process exits cleanly (defunct, exit status 0) and exactly one process stays alive.screencapturefails outright, andSystem EventsGUI-scripting queries were flaky/inconsistent even for basic window-count checks). The fix itself is grounded in a directly-confirmed gap (grep found zero activation calls) and a well-documented AppKit behavior, not a guess, but flagging that I could not visually reproduce-then-confirm-fixed on real hardware from here.src-tauri/tauri.conf.json+Cargo.toml/Cargo.lockto 0.1.15, added CHANGELOG entry.