What Is the openlogi-hook Crate? Cross-Platform Input Hooks for OpenLogi
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. 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, 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, 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) 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 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 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 (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.
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 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.
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 (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
HookEventandEventDispositioninlib.rsenable type-safe event handling with explicit control over event propagation. - Platform implementations reside in
macos.rs(CGEventTap),linux.rs(evdev/uinput), andwindows.rs(WH_MOUSE_LL). - The
Hook::startandHook::stopmethods manage the hook lifecycle on a background thread with automatic cleanup on drop. - Safety mechanisms including
source_is_remappableprevent 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) 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 at lines 490-492.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →