# What Is the openlogi-hook Crate? Cross-Platform Input Hooks for OpenLogi

> Discover the openlogi-hook crate, a cross-platform solution for capturing raw mouse and keyboard input events. Access global input with a unified Rust API.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-08-22

---

**The openlogi-hook crate provides a cross-platform, low-level input hook that captures raw mouse and keyboard events from the operating system, exposing them through a unified Rust API that abstracts away platform-specific implementations.**

The openlogi-hook crate serves as the foundational input layer for the AprilNEA/OpenLogi project, enabling higher-level components—such as the agent, GUI, and overlay—to observe and optionally modify raw input without requiring external services. According to the source code, this crate delivers a safe, ergonomic interface across macOS, Linux, and Windows while maintaining strict safety guarantees that prevent accidental system disruption.

## Core Event API and Architecture

At the heart of the openlogi-hook crate lies a stable event API defined in [`crates/openlogi-hook/src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hook/src/lib.rs). The primary types—`HookEvent`, `MouseEvent`, `KeyEvent`, and `EventDisposition`—allow callers to receive raw input and decide how each event should be handled.

The `HookEvent` enum and its related types are defined between lines 30-40 of [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs), providing a structured representation of input events. When an event occurs, the hook passes it to a user-provided callback that returns an `EventDisposition`, explicitly choosing whether to **pass through** the event to its original target or **consume** it.

## Platform-Specific Implementation Details

The crate abstracts three distinct platform implementations behind a common `Hook` interface, each handling the OS-specific machinery for input capture.

### macOS Implementation (CGEventTap)

On macOS, the crate utilizes `CGEventTap` to intercept events at the system level. The platform-specific logic resides in [`crates/openlogi-hook/src/macos.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hook/src/macos.rs), where `HookInner` manages the event tap lifecycle and accessibility permission handling. According to the source, `Hook::has_accessibility()` checks for required permissions before installation, and `Hook::list_event_taps()` (lines 455-459 in [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs)) provides diagnostic information about active event taps.

### Linux Implementation (evdev + uinput)

Linux systems use `evdev` for reading raw input events combined with `uinput` for re-injection when events are passed through. The implementation in [`crates/openlogi-hook/src/linux.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hook/src/linux.rs) handles the `evdev` device enumeration and `uinput` device creation necessary to establish the hook without requiring root privileges when udev rules permit access to input devices.

### Windows Implementation (WH_MOUSE_LL)

Windows employs the `WH_MOUSE_LL` low-level hook via `SetWindowsHookEx`. The [`windows.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/windows.rs) file contains the `HookInner` struct and callback translation logic that converts Win32 mouse messages into the crate's portable `MouseEvent` type, isolating platform-specific Win32 API interactions from the public interface.

## Hook Lifecycle and Control Flow

The `Hook` struct provides the primary interface for managing the input hook lifecycle. Calling `Hook::start` installs the platform-specific hook and spawns a background thread that executes the user-provided callback for every captured event. The implementation in [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs) (lines 45-78) shows that `Hook::start` returns a handle that remains active until `Hook::stop` is called or the handle is dropped, ensuring clean resource cleanup.

```rust
use openlogi_hook::{Hook, MouseEvent, EventDisposition};

fn main() -> Result<(), openlogi_hook::HookError> {
    // macOS requires Accessibility permission
    if !Hook::has_accessibility() {
        eprintln!("Grant Accessibility permission first");
        return Ok(());
    }

    // Install the hook; callback runs on background thread
    let hook = Hook::start(|event| {
        match event {
            openlogi_hook::HookEvent::Mouse(MouseEvent::Button { id, pressed, .. }) => {
                println!("Button {:?} {}", id, if pressed { "down" } else { "up" });
            }
            _ => {}
        }
        EventDisposition::PassThrough
    })?;

    // ... application logic ...

    hook.stop();
    Ok(())
}

```

This example demonstrates the essential pattern: checking permissions (macOS), installing the hook with a callback that pattern-matches on `HookEvent`, and explicitly stopping the hook for clean shutdown.

## Utility Functions and Diagnostics

Beyond event capture, [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs) exposes several utility functions between lines 470-490 for querying system state. `Hook::cursor_position()` returns the current mouse coordinates (lines 490-492), while `Hook::frontmost_application()` identifies the active window. On macOS, `Hook::list_event_taps()` enumerates existing CGEvent taps for debugging hook conflicts.

```rust
use openlogi_hook::Hook;

// Get current cursor position
if let Some(pos) = Hook::cursor_position() {
    println!("Cursor at ({}, {})", pos.x, pos.y);
}

// List active event taps (macOS diagnostic)
for tap in Hook::list_event_taps() {
    println!(
        "Tap {} – active: {}, enabled: {}, location: {:?}",
        tap.tap_id, tap.active, tap.enabled, tap.location
    );
}

```

## Safety Guarantees and Device Filtering

The openlogi-hook crate implements defensive mechanisms to prevent system instability. Defined in [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs) (lines 84-95), the `source_is_remappable` function helps callers identify which input sources can be safely modified, ensuring the hook never attempts to remap trackpads or other non-remappable hardware. The crate fails closed on unknown devices, preventing partial hook installation that could leave the system in an inconsistent state.

## Summary

- The **openlogi-hook crate** provides cross-platform low-level input hooks for macOS, Linux, and Windows through a unified Rust API.
- Core types like **`HookEvent`** and **`EventDisposition`** in [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs) enable type-safe event handling with explicit control over event propagation.
- Platform implementations reside in **[`macos.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/macos.rs)** (CGEventTap), **[`linux.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/linux.rs)** (evdev/uinput), and **[`windows.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/windows.rs)** (WH_MOUSE_LL).
- The **`Hook::start`** and **`Hook::stop`** methods manage the hook lifecycle on a background thread with automatic cleanup on drop.
- **Safety mechanisms** including `source_is_remappable` prevent accidental remapping of trackpads and ensure graceful failure on unsupported hardware.

## Frequently Asked Questions

### What platforms does the openlogi-hook crate support?

The crate supports macOS, Linux, and Windows. However, keyboard event capture is currently limited to macOS and Windows, while Linux supports mouse events only. Each platform uses native APIs: `CGEventTap` on macOS, `evdev`/`uinput` on Linux, and `WH_MOUSE_LL` on Windows.

### How does the crate handle required permissions on macOS?

On macOS, the hook requires Accessibility permissions to function. The API exposes `Hook::has_accessibility()` to check for these permissions before attempting installation, returning a clear error if permissions are missing rather than failing silently or crashing.

### What prevents openlogi-hook from interfering with trackpads or system input?

The crate implements `source_is_remappable` logic (lines 84-95 in [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs)) that identifies whether an input source is safe to remap. This safety check ensures trackpads and other critical input devices are never modified, preventing accidental system disruption or input loops.

### Can I use openlogi-hook to programmatically query cursor position without hooking events?

Yes. The crate provides `Hook::cursor_position()` as a standalone utility function that queries the current mouse coordinates without requiring an active hook. This function is available across all supported platforms and is defined in [`lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/lib.rs) at lines 490-492.