Make Escape cancel active recordings globally - #5
Open
amrshawqy wants to merge 1 commit into
Open
Conversation
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.
Why
Speaky's recording shortcut already works globally, but Escape cancellation did not follow the same model. Once focus moved to another application, Escape could be missed because the existing implementation used:
That made cancellation dependent on which application was focused. It also required a second Escape press, which is slower than the conventional “Escape cancels the active operation” behavior.
This PR establishes a simple contract:
What changed
Reliable global Escape handling
.cgSessionEventTapwith.defaultTap.RecordingState.recordingis active.nilfor Escape key-down so the focused application does not also act on it.Correct shortcut lifecycle
Escape now clears hands-free and active-key state, cancels pending Fn debounce work, and suppresses the matching physical key release. This prevents a held push-to-talk shortcut from restarting recording immediately after Escape cancels it.
Cancellation-safe start feedback
Rapid start → Escape → restart testing exposed an existing lifecycle race: the first recording's two-second start-sound task could outlive cancellation and mute the second recording.
The coordinator now owns exactly one start-feedback task:
This keeps the Escape workflow deterministic and prevents stale tasks from changing a later recording's audio state.
Clear permission guidance
Settings, onboarding, launch warnings, and the README now explain that Accessibility permission supports both auto-paste and reliable global Escape cancellation. The README also includes a focused manual verification checklist because CI cannot grant macOS Accessibility permission.
Tests and validation
git diff --checkpassed.Validation was also performed with the pending Dock and stable-build work from #3 and #4 to catch integration conflicts. This PR remains independently scoped and does not include either feature. The pinned dependency configuration from #4 was used because current
mainfollows FluidAudio's moving branch; this PR does not change dependencies.Manual verification
Scope
The PR does not change transcription, paste behavior, recording shortcuts, model handling, or release packaging. It is limited to Escape cancellation, the directly related recording-feedback lifecycle, permission messaging, and regression coverage.