# How OpenLogi Synthesizes Input Events Across macOS, Linux, and Windows

> OpenLogi synthesizes input events across macOS Linux and Windows by separating platform neutral definitions from OS specific injection logic Learn how OpenLogi dispatches to CoreGraphics uinput and Win32 SendInput APIs

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-09-04

---

**OpenLogi synthesizes input events by separating platform-neutral action definitions in `openlogi-core` from OS-specific injection logic in the `openlogi-inject` crate, dispatching to CoreGraphics APIs on macOS, uinput on Linux, and Win32 SendInput on Windows.**

OpenLogi is an open-source input automation framework that enables cross-platform event injection through a unified Rust API. The system achieves true portability by maintaining a strict architectural boundary between high-level user intentions and low-level OS driver interactions. This article examines how the AprilNEA/OpenLogi repository implements input synthesis across the three major desktop platforms.

## Architecture Overview

OpenLogi structures its input pipeline into two distinct layers. The **`openlogi-core`** crate defines platform-agnostic data structures like `Action` and `Effect`, while the **`openlogi-inject`** crate handles the actual OS-level event emission.

The entry point for all injection operations is the `openlogi_inject::execute` function defined in [`crates/openlogi-inject/src/inject.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject.rs). This function uses compile-time conditional compilation to select the appropriate platform backend:

```rust
// crates/openlogi-inject/src/inject.rs
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "windows")]
mod windows;

pub fn execute(action: &Action) {
    #[cfg(target_os = "macos")]
    macos::execute(action);
    #[cfg(target_os = "linux")]
    linux::execute(action);
    #[cfg(target_os = "windows")]
    windows::execute(action);
}

```

Each platform module translates the generic `Effect` variants into native API calls using the OS-specific input subsystems.

## Platform-Specific Implementation Details

### macOS: CoreGraphics and Private SPIs

On macOS, OpenLogi synthesizes input events through the **CoreGraphics** framework, specifically utilizing `CGEvent` APIs for standard input and private Dock SPIs for window management actions. The implementation resides in [`crates/openlogi-inject/src/inject/macos.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/macos.rs).

- **Keyboard Events**: The system calls `CGEvent::new_keyboard_event` with virtual key codes derived from the US keyboard layout, combining them with modifier flags constructed via `CGEventFlags`.
- **Unicode Text**: For layout-independent text entry, the code invokes `CGEventKeyboardSetUnicodeString` to post arbitrary Unicode characters directly.
- **Mouse Input**: Mouse clicks use `CGEvent::new_mouse_event` with `CGMouseButton` constants (left, right, center) and `OtherMouse` variants for back/forward buttons.
- **Media Keys**: These map to IOKit `NX_KEYTYPE_*` constants and post via `CGEventCreateKeyboardEvent`.
- **Window Manager**: Private functions like `CoreDockSendNotification` trigger Mission Control and App Exposé through undocumented Dock SPIs.

### Linux: Virtual Uinput Devices

The Linux implementation in [`crates/openlogi-inject/src/inject/linux.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/linux.rs) creates a virtual input device using the **uinput** kernel subsystem. This approach writes raw `input_event` structures directly to `/dev/input/eventN`, appearing to the system as a standard HID device.

- **Device Initialization**: A lazy singleton (`static DEVICE: LazyLock<Mutex<UinputDevice>>`) maintains a persistent virtual device handle.
- **Keyboard Synthesis**: Key presses emit as `EV_KEY` events with values 1 (press) and 0 (release), translating macOS `kVK_*` codes to Linux key codes via the internal `linux::keycode` mapping.
- **Mouse Buttons**: Physical button states use `BTN_LEFT`, `BTN_RIGHT`, and `BTN_MIDDLE` event codes.
- **Scroll Events**: Horizontal and vertical scrolling quantizes delta values into `EV_REL` events with `REL_HWHEEL` and `REL_WHEEL` axes.

### Windows: Win32 SendInput API

On Windows, OpenLogi utilizes the **`SendInput`** Win32 API to synthesize input, as implemented in [`crates/openlogi-inject/src/inject/windows.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/windows.rs). This API allows atomic injection of keyboard and mouse events by populating arrays of `INPUT` structures.

- **Keyboard Injection**: The system builds `INPUT_KEYBOARD` structures, mapping macOS `kVK_*` virtual key codes to Windows `VK_*` equivalents. The Cmd key maps to Ctrl for cross-platform consistency.
- **Mouse Injection**: Mouse clicks use `MOUSEEVENTF_LEFTDOWN`, `MOUSEEVENTF_LEFTUP`, `MOUSEEVENTF_RIGHTDOWN`, etc. Wheel events utilize `MOUSEEVENTF_WHEEL` and `MOUSEEVENTF_HWHEEL` for vertical and horizontal scrolling.
- **Input Arrays**: Multiple events are batched into a single `SendInput` call to ensure atomic delivery.

## The Platform-Neutral Core

The abstraction that enables cross-platform synthesis lives in [`crates/openlogi-core/src/binding/effect.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/effect.rs). The `Effect` enum defines all possible input operations without referencing any OS-specific types:

```rust
// crates/openlogi-core/src/binding/effect.rs
pub enum Effect {
    Click(MouseButton),
    Shortcut(Shortcut),
    Key(KeyCombo),
    HeldKey(KeyCombo),
    Scroll { dx: i32, dy: i32 },
    Media(MediaKey),
    Native(NativeAction),
    Script(Script<'_>),
    Text(&'static str),
    AgentSide,
    None,
}

```

Platform modules pattern-match on these variants. For example, a `Text` effect invokes `CGEventKeyboardSetUnicodeString` on macOS, writes a sequence of `EV_KEY` events on Linux, and sends `INPUT_KEYBOARD` events on Windows. This design allows the same high-level configuration to execute natively across all supported operating systems.

## Example: Injecting a Cross-Platform Shortcut

The following example demonstrates how client code initiates input synthesis without platform-specific knowledge:

```rust
use openlogi_core::binding::{Action, Shortcut};
use openlogi_inject::execute;

// Define a copy action (Cmd+C on macOS, Ctrl+C on Linux/Windows)
let shortcut = Shortcut::Copy;
let action = Action::new(shortcut);

// Execute platform-native injection
execute(&action);

```

When this code runs on macOS, `execute` dispatches to [`macos.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/macos.rs) and emits a `Command+C` via CoreGraphics. On Linux, the same call writes `Ctrl+C` keycodes to the uinput device. On Windows, it calls `SendInput` with `VK_CONTROL` and `VK_C` structures.

## Summary

- OpenLogi separates **action definitions** (`openlogi-core`) from **injection mechanics** (`openlogi-inject`) to maintain cross-platform compatibility.
- **macOS** implementations use CoreGraphics `CGEvent` APIs and private Dock SPIs for window management.
- **Linux** creates a virtual uinput device at `/dev/input/eventN` to emit `EV_KEY` and `EV_REL` events.
- **Windows** utilizes the Win32 `SendInput` API with `INPUT` structures for keyboard and mouse synthesis.
- The `Effect` enum in [`effect.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/effect.rs) provides a platform-neutral bridge that each OS module translates into native API calls.

## Frequently Asked Questions

### What API does OpenLogi use for input injection on macOS?

OpenLogi uses Apple's **CoreGraphics** framework, specifically `CGEventCreateKeyboardEvent` and `CGEventCreateMouseEvent` for standard input. For window management features like Mission Control, it calls private SPIs such as `CoreDockSendNotification` defined in Dock private headers.

### How does OpenLogi handle different keyboard layouts when synthesizing text?

On macOS, the framework calls `CGEventKeyboardSetUnicodeString` to inject Unicode characters directly, bypassing keyboard layout dependencies. On Linux and Windows, the platform modules map logical key identities to physical scan codes or virtual key codes, though the exact layout handling depends on the target system's configuration.

### Can OpenLogi synthesize media key events like play or pause?

Yes. The `Effect::Media` variant supports media keys across all platforms. On macOS, these map to IOKit `NX_KEYTYPE_PLAY`, `NX_KEYTYPE_NEXT`, and related constants. The Linux and Windows implementations emit the appropriate key codes for their respective media control standards.

### Where does the platform detection logic reside in the codebase?

Platform selection occurs at compile time in [`crates/openlogi-inject/src/inject.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject.rs) using `#[cfg(target_os = "...")]` attributes. The `execute` function statically dispatches to `macos::execute`, `linux::execute`, or `windows::execute` based on the target triple, eliminating runtime overhead for platform detection.