fix(hotkey): a microphone that closed itself does not cost the next double-tap - #61
Merged
hannesreinsch merged 1 commit intoSep 9, 2026
Conversation
…ouble-tap
"When the microphone closes automatically, the double press control doesn't
reset."
`recording` was a local flag in `listen_double_tap` and the only record of
whether anything was running — true when nothing else could end a clip. The
microphone can now close itself, after fifteen seconds of silence or the
two-minute cap, so the clip was gone while the loop still believed it was
running: the next tap was spent being a STOP for something already stopped,
and the double-tap only worked on the try after that.
The loop asks instead. `is_recording` is an optional callback polled once per
poll — `lambda: bool(mine)` in the daemon, a list lookup and never work — and a
clip that ended without a tap resets the gesture on the spot (`saw("ended")`,
so the log says which). Given none, the loop behaves exactly as it always did,
and a test pins that half too.
It also fixes a case that was always wrong: an `on_start` that could not open
the microphone left `recording` true, so the next tap was spent stopping a clip
that never existed.
`_tap_the_key` drives the real loop over a scripted key sequence with its clock
and its key reader replaced, so a double-tap takes microseconds and no real key
is touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P7oJz8M9QzsdJimoM318cj
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe double-tap listener now accepts recording-state callbacks. The listening loop supplies microphone state, and the listener resets stale state when a recording closes independently. Tests cover both the new behavior and legacy behavior without the callback. ChangesRecording state synchronization
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant listen_loop
participant bind_trigger
participant listen_double_tap
participant microphone_state
participant on_tap
listen_loop->>bind_trigger: pass is_recording callback
bind_trigger->>listen_double_tap: forward callback
listen_double_tap->>microphone_state: poll recording state
microphone_state-->>listen_double_tap: report recording ended
listen_double_tap->>on_tap: emit "ended"
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
hannesreinsch
deleted the
fix/the-gesture-resets-when-the-mic-closes-itself
branch
September 9, 2026 14:40
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
recordingwas a local flag insidelisten_double_tapand the only record of whether anything was running. That was true while nothing else could end a clip.The microphone can now close itself — after fifteen seconds of silence, or the two-minute cap. So the clip was gone while the loop still believed it was running: the next tap was spent being a STOP for something already stopped, and the double-tap only worked on the try after that.
The fix
The loop asks instead of assuming.
is_recordingis an optional callback polled once per poll —lambda: bool(mine)in the daemon, a list lookup and never work. A clip that ended without a tap resets the gesture on the spot, and says so in the log (saw("ended")).Given no callback, the loop behaves exactly as it always did — a second test pins that half, so the change cannot quietly become the new behaviour everywhere.
It also fixes a case that was always wrong: an
on_startthat could not open the microphone leftrecordingtrue, so the next tap was spent stopping a clip that never existed.The driver
_tap_the_keyruns the reallisten_double_tapover a scripted key sequence with its clock and its key reader replaced, so a double-tap takes microseconds and no real key is touched. The test starts a clip, has the watchdog end it between the pairs, and asserts the second double-tap starts rather than stops.Gate
208 passed, ruff clean, mypy clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01P7oJz8M9QzsdJimoM318cj
Summary by CodeRabbit
Bug Fixes
Tests