Skip to content

feat: add macOS support#129

Open
peteonrails wants to merge 41 commits intomainfrom
feature/macos-release
Open

feat: add macOS support#129
peteonrails wants to merge 41 commits intomainfrom
feature/macos-release

Conversation

@peteonrails
Copy link
Copy Markdown
Owner

@peteonrails peteonrails commented Jan 27, 2026

Summary

This PR adds macOS support to Voxtype, making the push-to-talk daemon usable on Apple desktop systems.

Scope

  • CGEventTap-based global hotkey detection, including FN/Globe key support via SecondaryFn flag detection.
  • Native macOS text output through CGEvent injection, with osascript and pbcopy fallbacks.
  • macOS menu bar integration and system notifications.
  • macOS build, signing, notarization, DMG packaging, and Homebrew formula support.
  • macOS fixes for modifier flags, Metal audio context alignment, and short-clip Whisper context behavior.

This PR is intentionally macOS-only. The OpenAI-compatible local STT API service is tracked separately in #245, and the branch that stacks both for local Mac use is feature/macos-openai-stt-stack.

Current State

  • Branch feature/macos-release was updated with main on April 23, 2026.
  • GitHub reports the PR as mergeable, with branch protection/checks still blocking merge.

Verification

No new verification was run in this session after merging main into this PR branch. The branch should still be validated by the required GitHub checks before merge.

@krystophny
Copy link
Copy Markdown
Collaborator

Great to see that going forward @peteonrails and happy to help! Just curious about the pro license system, since the code is MIT licensed right now. Do you plan to make this project commercial?

@peteonrails
Copy link
Copy Markdown
Owner Author

peteonrails commented Jan 27, 2026

Great to see that going forward @peteonrails and happy to help! Just curious about the pro license system, since the code is MIT licensed right now. Do you plan to make this project commercial?

@krystophny

No, this project will always be free and MIT licensed. I was experimenting with a Pro plugin that added some extra features, and I considered making the parakeet version be a part of that, but I have shelved that idea.

My original MacOS code was going to have a Pro tier as well, but I similarly ditched that idea, especially in light of open source contribs coming in for the MacOS branch

What I may end up doing is selling a license for support, which wouldn't be likely to need any binary support.

EDIT to add: I pulled all of the experimental Pro License code out and squashed my commits so as not to make anyone confused about my intent.

@peteonrails peteonrails force-pushed the feature/macos-release branch 2 times, most recently from 9d8412f to 301db56 Compare January 28, 2026 00:51
@krystophny
Copy link
Copy Markdown
Collaborator

Great to see that going forward @peteonrails and happy to help! Just curious about the pro license system, since the code is MIT licensed right now. Do you plan to make this project commercial?

@krystophny

No, this project will always be free and MIT licensed. I was experimenting with a Pro plugin that added some extra features, and I considered making the parakeet version be a part of that, but I have shelved that idea.

My original MacOS code was going to have a Pro tier as well, but I similarly ditched that idea, especially in light of open source contribs coming in for the MacOS branch

What I may end up doing is selling a license for support, which wouldn't be likely to need any binary support.

EDIT to add: I pulled all of the experimental Pro License code out and squashed my commits so as not to make anyone confused about my intent.

I see. Don't worry, I fully understand, since you will need to pay Apple in case you provide a signed binary distribution. Maybe the easiest option would be to make the code-signed binary version an app where people pay, but keep the code still free for the ones who build it themselves? That way I'm sure one could generate some revenue (especially when also supporting iOS at some point)

@peteonrails
Copy link
Copy Markdown
Owner Author

Great to see that going forward @peteonrails and happy to help! Just curious about the pro license system, since the code is MIT licensed right now. Do you plan to make this project commercial?

@krystophny
No, this project will always be free and MIT licensed. I was experimenting with a Pro plugin that added some extra features, and I considered making the parakeet version be a part of that, but I have shelved that idea.
My original MacOS code was going to have a Pro tier as well, but I similarly ditched that idea, especially in light of open source contribs coming in for the MacOS branch
What I may end up doing is selling a license for support, which wouldn't be likely to need any binary support.
EDIT to add: I pulled all of the experimental Pro License code out and squashed my commits so as not to make anyone confused about my intent.

I see. Don't worry, I fully understand, since you will need to pay Apple in case you provide a signed binary distribution. Maybe the easiest option would be to make the code-signed binary version an app where people pay, but keep the code still free for the ones who build it themselves? That way I'm sure one could generate some revenue (especially when also supporting iOS at some point)

Yeah, I like that idea - And on a related note: I would make the Linux binary distributions free, because Omarchy pulls in the binaries as opposed to forcing users to build, and NixOS needs them too.

@peteonrails peteonrails force-pushed the feature/macos-release branch 4 times, most recently from fbdfbc7 to 47b35d3 Compare January 29, 2026 23:24
peteonrails and others added 14 commits January 31, 2026 13:08
Platform support:
- CGEventTap-based global hotkey detection (FN/Globe key)
- CGEvent text injection with osascript fallback
- pbcopy clipboard integration
- Native menu bar and system notifications
- Hammerspoon integration for advanced users

Build and distribution:
- Universal binary build script (x86_64 + arm64)
- Code signing and notarization scripts
- DMG packaging with drag-to-Applications
- Homebrew formula
- LaunchAgent for auto-start

Fixes:
- CGEvent modifier flags: prevent Caps Lock causing random capitalization
- Metal backend crash: align audio_ctx to multiple of 8
- Whisper hallucination: set no_context=true to prevent phrase repetition

Co-authored-by: Christopher Albert <albert@tugraz.at>
- Add native SwiftUI setup app (macos/VoxtypeSetup/)
  - Setup wizard: permissions, model download, LaunchAgent
  - Preferences panel for ongoing configuration
  - Calls voxtype CLI for actual operations
- Improve menubar and notification handling
- Enhance macOS setup CLI as fallback
- Update config and error handling for macOS
- CONFIGURATION.md: Restore CLI backend docs (backend="cli", whisper_cli_path)
- TROUBLESHOOTING.md: Restore X11, keyboard layout, and FFI crash sections
- INSTALL.md: Restore Fedora ydotool system service notes
- Update version for macOS release candidate
- Add Christopher Albert, André Silva, goodroot, Chmouel Boudjnah,
  Alexander Bosu-Kellett, ayoahha, and Thinh Vu to authors
- Add Homebrew formula for macOS installation
Stale build artifacts can cause GPU support to silently fail at runtime
even when:
- The build succeeds without errors
- Binary size and checksum differ from previous builds
- Version reports correctly

Added warnings about running cargo clean before building with different
feature sets, and a new "Functional Verification" section explaining how
to verify GPU builds actually detect the GPU at runtime.
The rdev crate (for global hotkeys) and tray-icon crate require X11
and GTK development libraries on Linux. Added:
- libx11-dev, libxi-dev, libxtst-dev (X11 input)
- libgtk-3-dev, libglib2.0-dev, libappindicator3-dev (system tray)

This fixes Docker builds after the macOS merge which added these
dependencies via the tray-icon crate.
- Fix model selection to use static model lists (prevents infinite re-render loops)
- Add real-time download progress bar that monitors file size on disk
- Fix permissions flow to use manual confirmation (Open Settings + Done buttons)
- Fix LaunchAgent detection to check for success message
- Fix CLI command syntax for model downloads and engine switching
- Tighten layouts to prevent button clipping on all screens
- Add proper wizard completion state tracking
- Fix PreferencesView to avoid @StateObject render loops
- Add entitlements for AppleScript automation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
macOS builds now always include Parakeet support via --features parakeet.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Detect quantized model files (.int8.onnx) in addition to standard .onnx
- Skip Whisper model check when using Parakeet engine
- Show helpful message that Whisper model is not required for Parakeet

The setup check was failing to find parakeet-tdt-0.6b-v3-int8 because it
only looked for encoder-model.onnx and decoder_joint-model.onnx, not
the quantized variants with .int8.onnx extension.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cask approach:
- Installs prebuilt DMG to /Applications/Voxtype.app
- Creates CLI symlink in $(brew --prefix)/bin
- Works around Homebrew sandbox restrictions
- Adds caveat for xattr quarantine removal if needed

Formula updates:
- Creates app bundle in Homebrew prefix during post_install
- Symlinks to ~/Applications for permission grants
- Adds service support via brew services
- Updated caveats with permission grant instructions

The Cask is the recommended installation method for most users.
The Formula remains available for building from source.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rebuilt the macOS DMG after the Parakeet model detection fix was
applied. The new DMG contains a binary that correctly detects
quantized .int8.onnx model files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Install LaunchAgent plist during brew install
- Load the agent so daemon starts immediately
- Auto-restart daemon if it crashes (KeepAlive)
- Unload and remove LaunchAgent on uninstall
- Updated caveats to reflect auto-start behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Run xattr -cr on app bundle to remove Gatekeeper quarantine
- Simplify caveats now that xattr is automatic
- Users no longer need manual steps to bypass "damaged app" error

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
peteonrails and others added 5 commits January 31, 2026 13:32
- Update DMG build script to bundle VoxtypeMenubar and VoxtypeSetup apps
- Include engine notification icons (parakeet.png, whisper.png)
- Auto-run setup and download model during brew install
- Launch menubar app automatically after installation
- Update caveats with cleaner instructions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- VoxtypeSetup opens to Permissions tab on first launch
- Cask starts daemon and opens Settings for permission granting
- Updated caveats to guide user through permission setup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New toggle in General settings to show/hide menubar icon
- Launches VoxtypeMenubar.app when enabled
- Quits menubar app when disabled

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update version to 0.6.0-rc.2
- Document all 7 required Linux binaries: avx2, avx512, vulkan,
  parakeet-avx2, parakeet-avx512, parakeet-cuda, parakeet-rocm
- Update build instructions to include parakeet-cuda (Docker/NVIDIA)
  and parakeet-rocm (local/AMD) builds
- Regenerate Cargo.lock
- Fix dtolnay/rust-action -> dtolnay/rust-toolchain (non-existent action)
- Add chmod 755 in Dockerfiles to fix permission errors on mounted volumes
- Remove redundant chmod from build-linux.yml (Docker handles it now)
- Add missing GTK/X11 dev dependencies to test-packages.yml and AVX-512 builds
- Add protobuf deps for Parakeet AVX-512 build
@krystophny krystophny mentioned this pull request Feb 3, 2026
3 tasks
Creates /Applications/Voxtype.app bundle and adds to Login Items.
This is the recommended way to run voxtype on macOS because:

- App bundles can be granted Accessibility, Input Monitoring, and
  Microphone permissions properly
- Login Items inherit these permissions (launchd services don't)
- Clean auto-start on login without extra wrapper scripts
- Runs both daemon and menu bar icon

Usage:
  voxtype setup app-bundle           # Install
  voxtype setup app-bundle --status  # Check status
  voxtype setup app-bundle --uninstall

The launchd option is kept for users who don't need microphone
(e.g., using remote transcription), but app-bundle is recommended.
- macos.rs wizard now delegates to app_bundle::create_app_bundle()
  instead of duplicating app bundle creation with a different bundle ID
- macos.rs autostart now uses Login Items (via app_bundle) instead of
  launchd, which does not receive Microphone permissions
- launchd.rs install() warns that it lacks mic permissions on macOS
  and recommends app-bundle instead
- run_setup() "Next steps" are now platform-aware: macOS shows
  app-bundle/macos wizard instructions, Linux shows compositor/systemd
- Default hotkey suggestion in wizard changed from rightalt to fn
- Removed install_launchd_with_app_bundle() and duplicate constants
@krystophny
Copy link
Copy Markdown
Collaborator

krystophny commented Feb 5, 2026

Hey! I've been testing this on my Mac and with two small additions everything is working really nicely now. I opened these as separate PRs against this branch:

(There's also #171 for CI workflow fixes, but that's independent.)

I'm actually dictating Claude to write this comment via voxtype right now using the FN key - works great with the large-v3-turbo model on Apple Silicon!

peteonrails and others added 9 commits February 15, 2026 16:43
Add FN/Function/Globe key support for macOS
Add macOS app bundle setup with Login Items autostart
…release

Merge main into feature/macos-release and resolve conflicts
…ion handling

- Fix self-copy corruption: skip copy when source == dest, use temp file
  + atomic rename otherwise to prevent truncation when updating from
  within the app bundle itself
- Fix code signing: sign voxtype-bin individually before signing the
  bundle so the Mach-O gets proper code page hashes (was SIGKILL'd)
- Replace wrapper script with direct binary launch: set voxtype-bin as
  CFBundleExecutable and add hidden AppLaunch command that starts daemon
  in background + menubar in foreground. The wrapper script's exec()
  broke macOS Control Center's XPC scene registration, preventing the
  menubar icon from appearing
- Auto-launch after install: run open Voxtype.app at end of setup
- Implement real Accessibility permission check using CGEventTapCreate
  (not AXIsProcessTrusted which caches per-process) with auto-restart:
  daemon polls every 2s and restarts itself when permission is granted
- Prompt for Accessibility via AXIsProcessTrustedWithOptions on startup
- Reset TCC entries only when the binary actually changed to avoid
  wiping permissions on self-copy reinstalls
…dates

State file changes are now picked up via notify (kqueue on macOS)
instead of polling every 500ms, eliminating the visible delay between
hotkey press and icon update.
@krystophny
Copy link
Copy Markdown
Collaborator

krystophny commented Feb 25, 2026

@peteonrails I merged in main again and added d047e66 and b8b83a3 as quality-of-life improvement for installation and snappier menubar icon. Is this OK if you review those individually (I thought it's easier than creating new branches again)? Are we close to merging this branch back to main?

@krystophny krystophny marked this pull request as ready for review March 1, 2026 08:54
@sebassdc sebassdc mentioned this pull request Mar 15, 2026
11 tasks
@krystophny
Copy link
Copy Markdown
Collaborator

@peteonrails @digunix @DuskyElf this is working fine for me now for two months in practical use. In fact, I'm typing this also with voxtype on my M1 macbook with v3-large-turbo. Do you think we can merge it?

@krystophny
Copy link
Copy Markdown
Collaborator

PS: I saw your PR only now @sebassdc ... maybe this needs a discussion which way to go, since yours is much more compact in terms of required changes.

@krystophny
Copy link
Copy Markdown
Collaborator

@peteonrails I am now using this successfully for quite some time on mac. Do you think we can merge it soon? Or go for the solution of #263 instead? I again merged main into the branch as rebase is too difficult due to the long time this PR is open.

@krystophny krystophny changed the title Add macOS support feat: add macOS support Apr 23, 2026
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