What APIs Does FluidVoice Use for Text Insertion? A Complete Technical Breakdown

FluidVoice uses a seven-layer fallback pipeline of macOS APIs for text insertion, ranging from fast CGEvent Unicode injection to reliable clipboard-based paste operations, as implemented in TypingService.swift.

FluidVoice is an open-source macOS voice dictation application that needs to inject transcribed text into any target application reliably. According to the altic-dev/FluidVoice source code, this requires a sophisticated multi-strategy approach that gracefully degrades when faster methods fail. The core insertion logic lives in Sources/Fluid/Services/TypingService.swift, where each API is attempted in priority order based on speed and compatibility.

The Seven-Layer Text Insertion Pipeline

FluidVoice's insertTextInstantly(_:preferredTargetPID:) method orchestrates a cascading fallback system. The pipeline first checks the user's chosen text insertion mode (.standard or .reliablePaste) before proceeding through these API layers:

CGEvent Unicode Insertion (Direct Typing)

The fastest path uses Core Graphics event injection to send Unicode characters directly to a target process identifier.

  • Method: insertTextBulkInstant
  • Mechanism: Creates CGEvent objects with Unicode string payloads and posts them to a specific PID
  • Best for: Terminal applications, Electron apps, and processes with reliable PID targeting
// Direct CGEvent unicode insertion (bulk)
let success = typingService.insertTextBulkInstant("Hello, world!", targetPID: 12345)

This approach bypasses the macOS input system entirely, making it both fast and resistant to interference from input method editors.

Accessibility API Insertion

When CGEvent fails or no PID is available, FluidVoice falls back to the Accessibility framework to manipulate the focused UI element.

  • Method: insertTextViaAccessibility
  • Mechanism: Uses AXUIElementSetAttributeValue to set the AXValue of the focused element, then positions the caret
  • Best for: Standard Cocoa applications with properly exposed accessibility trees
// Accessibility insertion
let success = typingService.insertTextViaAccessibility("Hello, world!")

This method requires the target application to implement accessibility support, but works where low-level event injection is blocked.

HID-Level CGEvent Insertion

For scenarios where no focused PID can be determined, FluidVoice uses HID-level event simulation that mimics a physical keyboard at the hardware abstraction layer.

  • Method: insertTextBulkHIDInstant
  • Mechanism: Creates CGEvent keyboard events without PID targeting, relying on the system to route them
  • Best for: Global insertion when target identification fails
// HID-level CGEvent insertion (no PID)
let success = typingService.insertTextBulkHIDInstant("Hello, world!")

Clipboard-Based Insertion (Global Paste)

The most reliable fallback copies text to the system clipboard and simulates Command+V paste.

  • Method: tryReliablePasteInsertioninsertTextViaClipboard
  • Mechanism: Temporarily replaces clipboard contents, issues paste keystroke, then (optionally) restores original clipboard
  • Best for: Applications that reject direct event injection but accept standard paste operations
// Clipboard-based insertion (global)
let success = typingService.insertTextViaClipboard("Hello, world!")

Clipboard-to-PID Insertion (Targeted Paste)

A refinement of the clipboard method that activates a specific target process before pasting.

  • Method: insertTextViaClipboardToPid
  • Mechanism: Activates target PID, performs clipboard paste, with optional foreground activation
  • Best for: Applications like Ghostty that require explicit activation for paste to succeed
// Clipboard-to-PID insertion (targeted)
let success = typingService.insertTextViaClipboardToPid(
    "Hello, world!", targetPID: 12345, activateTargetFirst: true)

When keyboard shortcuts fail, FluidVoice programmatically triggers the Edit → Paste menu command.

  • Method: insertTextViaMenuPaste
  • Mechanism: Uses Accessibility API to locate and click the Paste menu item
  • Best for: Applications with non-standard keyboard handling or disabled shortcuts
// Menu-based paste insertion
let success = typingService.insertTextViaMenuPaste("Hello, world!")

Character-by-Character Typing

The final fallback types each character individually with small delays between keystrokes.

  • Location: Loop starting at line 84 in insertTextInstantly
  • Mechanism: HID-level events with usleep delays between each character
  • Best for: Hostile environments where all bulk methods fail
// Character-by-character fallback (automatic via pipeline)
typingService.insertTextInstantly("Hello, world!", preferredTargetPID: nil)

Key Source Files and Architecture

File Purpose
Sources/Fluid/Services/TypingService.swift Central orchestration of all insertion APIs and the fallback pipeline
Sources/Fluid/Services/ClipboardService.swift Clipboard state management for paste-based insertion paths
Sources/Fluid/Services/TranscriptionProvider.swift Provides transcribed text consumed by TypingService
Tests/FluidDictationIntegrationTests/TypingServiceTransientPasteboardTests.swift Unit tests verifying clipboard insertion correctness

The pipeline includes comprehensive logging from line 350 onward in TypingService.swift, enabling debugging of which API succeeded or failed for any given insertion attempt.

Comparison of Text Insertion APIs

API Layer Speed Reliability Setup Required
CGEvent Unicode Fastest Moderate Target PID
Accessibility Fast Moderate AX permissions
HID CGEvent Fast Moderate None
Global Clipboard Moderate High None
Clipboard-to-PID Moderate High Target PID
Menu Paste Slow High AX permissions
Character-by-character Slowest Highest None

Summary

  • FluidVoice's text insertion relies on TypingService.swift to coordinate seven distinct macOS APIs in a prioritized fallback chain.
  • CGEvent Unicode injection provides the fastest path when targeting a known PID, while clipboard-based paste operations offer the most reliable cross-application compatibility.
  • The pipeline automatically escalates from high-speed, low-reliability methods to slower, more robust alternatives based on real-time success detection.
  • Developers integrating similar functionality should study insertTextInstantly(_:preferredTargetPID:) for patterns on graceful degradation and user-configurable insertion modes.

Frequently Asked Questions

Does FluidVoice require accessibility permissions for all text insertion methods?

No. Only the Accessibility API insertion and menu-based paste methods require Accessibility permissions. The CGEvent and HID-level methods function without additional permissions, though they may be blocked by certain application sandboxing configurations. The clipboard-based methods require no special permissions beyond standard pasteboard access.

How does FluidVoice handle clipboard restoration after paste insertion?

According to Sources/Fluid/Services/ClipboardService.swift, the implementation uses a transient pasteboard pattern. The original clipboard contents are preserved before insertion and restored after the paste operation completes (usually within milliseconds). This prevents dictation from corrupting the user's clipboard state, with unit tests in TypingServiceTransientPasteboardTests.swift verifying this behavior.

Why does FluidVoice need multiple text insertion APIs instead of just using paste?

Single-method approaches fail across macOS's diverse application ecosystem. Terminal applications often ignore paste operations in certain modes, Electron apps may block Accessibility API, games and full-screen apps frequently intercept all standard input, and sandboxed applications restrict cross-process event injection. The seven-layer pipeline ensures FluidVoice functions regardless of target application architecture or security posture.

Can I force FluidVoice to use a specific insertion API?

Yes. The insertTextInstantly method respects a text insertion mode parameter. Set .standard to attempt the full fast-to-slow pipeline starting with CGEvent, or .reliablePaste to skip directly to clipboard-based methods. Advanced users can also call individual methods like insertTextViaClipboard directly, though these are typically internal to the service.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →