Skip to content

fix: let Fn chords pass through during dictation - #1767

Draft
smkwray wants to merge 1 commit into
cjpais:mainfrom
smkwray:agent/fn-modifier-passthrough
Draft

fix: let Fn chords pass through during dictation#1767
smkwray wants to merge 1 commit into
cjpais:mainfrom
smkwray:agent/fn-modifier-passthrough

Conversation

@smkwray

@smkwray smkwray commented Jul 22, 2026

Copy link
Copy Markdown

Problem

On macOS, binding bare Fn as push-to-talk makes Handy consume the modifier. The shortcut path constructs HotkeyManager with new_with_blocking(), so ordinary chords such as Fn+Delete, Fn+arrows, and Fn+function keys do not reach the focused app while Handy is running.

Change

The shortcut manager observes events through KeyboardListener and matches registered shortcuts in Handy instead of grabbing them through the blocking manager.

For bare-Fn transcription:

  • Fn-down starts recording and Fn-up transcribes
  • a keyboard key joining the Fn chord cancels dictation while that key passes through
  • mouse input does not cancel dictation
  • the Fn transcription binding stays suppressed until Fn is released, preventing a single chord from immediately restarting recording

Cancellation is serialized through TranscriptionCoordinator so a key joining the chord cannot race a still-running start request. The coordinator uses a non-recursive cancellation path rather than sending another cancel command to its own channel.

Scope and design question

This is a draft because the observe-without-grab behavior may belong in handy-keys rather than Handy. I described the adjacent push-to-talk case on handy-computer/handy-keys#10. That issue concerns toggle-mode activation on key-up when a modifier was used alone; this PR does not claim to fix it.

The behavior has been tested on Apple Silicon macOS, not Windows or Linux. The current implementation also identifies the two transcription bindings and the literal fn shortcut explicitly. I would generalize or platform-scope that code based on maintainer direction rather than assume the preferred cross-platform API.

Validation

  • npm run build: passed
  • cargo fmt -- --check: passed
  • cargo clippy --lib: passed with the existing unused-assignment warning in src/managers/transcription.rs:1178
  • cargo test --lib: 133 passed, 1 failed
    • both new Fn tests passed
    • the failure is the current-main catalog assertion: moss is present in the catalog but absent from KNOWN_ARCHES; this patch does not touch catalog or model-capability code

The same patch was built from v0.9.4 and manually exercised on an Apple M1 Ultra. Bare Fn recorded and transcribed, Fn+Delete cancelled while Delete reached the focused app, mouse input did not cancel, the shortcut remained suppressed until Fn release, Escape cancellation worked, and Karabiner/Caps Lock-generated Fn events did not leave Handy stuck.

AI assistance

Codex implemented, rebased, and tested the patch under the contributor's direction. Claude Opus reviewed the scope and PR wording. The contributor manually validated the behavior on macOS.

@cjpais

cjpais commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Thank you for writing this and I do understand the problem and we probably should fix this as well. It will take me some time to review your PR because there are a load of keyboard-related issues right now that I'm slowly poking through, but eventually this probably will be merged in some form

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.

2 participants