About this project

## Project Overview AirPods Voice Input Method is a native macOS menu bar app that uses AirPods click gestures to control voice input: click once to start recording, click again to stop, confirm the text, and send it automatically, all without touching the keyboard. The current official version is 1.0. ## Main Features - Click AirPods once to start voice input, click again to stop and send automatically. - Supports multiple consecutive rounds; after each round it returns to an idle state ready to start again. - Compatible with the built-in microphone and the AirPods microphone, with no need to change app settings. - By default simulates a long press of `Fn`, and can also be configured as Control, Option, Command, Shift, or F1–F12. - The menu bar and control window provide running status, start, stop, usage instructions, and quit. - The control window is shown each time the app opens; after closing it, the app continues running in the menu bar. - Physical keyboard input automatically aborts an unfinished voice key press, preventing modifier keys from affecting terminals or to-do software. - Does not occupy the Dock and does not depend on third-party automation software such as BetterTouchTool. - Supports Apple Silicon and Intel Macs, with a minimum requirement of macOS 13. ## Prerequisites You need to set the voice input shortcut in your own voice input method to "long press Fn". The README states that 1.0 has completed multi-round acceptance testing with physical AirPods using the Doubao input method; other input methods must support the behavior of "hold the shortcut to record, release to finish". While the app is running, it takes over the AirPods play/pause click, so music cannot be controlled with a click at that time; after stopping or quitting the app, media control is restored. ## Installation and Permissions Download the PKG installer from GitHub Releases and install it to `/Applications/AirPods Voice 输入法.app`. The installer automatically stops and removes old beta versions to avoid two versions taking over AirPods at the same time. The current installer uses ad-hoc signing; if macOS blocks it, right-click in Finder and choose "Open". The app must obtain macOS "Accessibility" permission in order to simulate the long-press voice key and send Return. The authorization target is the app itself; there is no need to authorize Terminal or development tools, and Full Disk Access is not required. The app itself does not capture the microphone; microphone permission is managed by the voice input method selected by the user. ## How It Works (README Description) The app uses `MPRemoteCommandCenter` to hold a Now Playing session to receive AirPods clicks, and only accepts media events whose source is `com.apple.bluetoothd` or `com.apple.cloudpaird`; other sources such as keyboard play keys will not start voice input. After the AirPods microphone enters call audio mode, the second click is reported by `bluetoothd` as Software Mute, and the app treats it as a stop-and-send signal only within a voice session it has already started. IOHID monitoring serves as a backup channel, and the same physical operation is deduplicated through a 350ms window. The first click sends one Fn activation via `IOHIDPostEvent`; the second click ends the recording session and sends two Returns in sequence, the first to confirm the input method's composed text and the second to send the message. To avoid global modifier keys affecting shortcut-sensitive apps, 1.0 adds three layers of protection: clean up historical residual Fn at startup; during voice input, if physical keyboard input is detected, first remove the voice modifier key and immediately end voice input; if the app exits abnormally, an independent daemon process releases Fn. On normal stop, foreground app switching, the 5-minute safety timeout, or app exit, only the key is released and no accidental send occurs. ## Configuration and Logs The default configuration file is `config/voice-key`, with the content `fn`; it can be changed to control, option, command, shift, or f1–f12, and the script must be restarted after modification. It can also be temporarily specified via environment variables when running from source. Logs are located under `/tmp/airpods-voice-input-method/` as app.log, app.stdout.log, and app.stderr.log. You can use `pgrep -fl airpods-voice-input-method` to confirm the process, and `./scripts/stop.sh` to safely stop it and release the voice key. ## Build and Test `scripts/build.sh` is provided to build the universal app, and `scripts/package-release.sh` generates the PKG, with support for specifying a Developer ID certificate. The test scripts cover regression scenarios such as four rounds of voice interaction, Fn consumption, keyboard safety, and crash recovery. There is also `tests/hitl-two-cycle.sh` for manual acceptance testing with physical AirPods. ## License The source code uses the PolyForm Noncommercial 1.0.0 license, which is source-available rather than an OSI-defined open source license; personal learning, research, and non-commercial use are permitted, while commercial use requires separate authorization.