# How OpenLogi Handles Custom Shortcuts and Text Input: Architecture Deep Dive

> Explore OpenLogi's architecture to understand how it handles custom shortcuts and text input across Windows, macOS, and Linux, leveraging native injection and GPUI components for seamless operation.

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

---

**OpenLogi parses shortcut strings into platform-neutral `KeyCombo` structures, stores them as `Action::CustomShortcut` values, and injects them natively on Windows, macOS, and Linux via the `openlogi-inject` crate, while GPUI-based components in the desktop layer handle text input for configuration.**

The [AprilNEA/OpenLogi](https://github.com/AprilNEA/OpenLogi) repository implements a cross-platform automation engine that abstracts keyboard shortcuts through a unified parsing and injection pipeline. Understanding how OpenLogi handles custom shortcuts and text input reveals a clean separation between neutral data models in the core crate and platform-specific injection logic. This architecture allows users to define shortcuts in a common format while the system adapts execution to the host operating system.

## Parsing Shortcuts with the KeyCombo Abstraction

At the heart of OpenLogi's shortcut system lies the **`KeyCombo`** struct, a platform-agnostic representation of key combinations. The parser resides in [[`crates/openlogi-core/src/binding/key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/key_combo.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/key_combo.rs), where the `parse` method converts human-readable strings like `"Cmd+Shift+P"` into structured data.

The parser handles modifier normalization and key validation, ensuring that `"Ctrl+Alt+Delete"` and platform-specific variants resolve to consistent internal representations. Once parsed, these `KeyCombo` instances become immutable values that flow through the action system without requiring re-parsing.

## Storing Actions and Configuration Persistence

Parsed shortcuts integrate with OpenLogi's action system through the **`Action::CustomShortcut`** variant. The core binding layer defines this enum to represent both immediate shortcuts and held-key combinations (`Action::HoldShortcut`). Configuration persistence is demonstrated in [[`crates/openlogi-core/src/binding/tests.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/tests.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/tests.rs), which validates round-trip serialization through TOML.

When users configure shortcuts via the desktop interface, the application stores these actions in the global state. The action-ring component then routes triggered shortcuts to the injection layer, maintaining a clean boundary between UI configuration and system execution.

## Cross-Platform Injection Architecture

The `openlogi-inject` crate provides the bridge between neutral `KeyCombo` values and native OS input APIs. Each platform implementation maps the abstract key combination to system-specific virtual keycodes or events.

### Windows Implementation

On Windows, [[`crates/openlogi-inject/src/inject/windows.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/windows.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-inject/src/inject/windows.rs) translates `KeyCombo` instances into virtual-key chords. The `post_custom_shortcut` function constructs the appropriate input structures and dispatches them via the Windows input API. The implementation includes guard clauses that log warnings when attempting to inject unsupported held shortcuts, preventing silent failures.

### macOS Implementation

The macOS layer in [[`crates/openlogi-inject/src/inject/macos.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/macos.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-inject/src/inject/macos.rs) handles Carbon and Cocoa input synthesis. It converts the neutral key identifiers to macOS-specific keycodes and modifier masks before posting events to the system event queue. Like the Windows implementation, it validates shortcut feasibility against platform constraints.

### Linux Implementation

For Linux systems, [[`crates/openlogi-inject/src/inject/linux.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/linux.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-inject/src/inject/linux.rs) provides the `press_combo` function, which maps `KeyCombo` values to Linux input event codes. The implementation handles the translation of modifier keys and ensures proper sequencing of press and release events for the target display server.

```rust
// Example: Defining and injecting a custom shortcut across platforms
use openlogi_core::binding::KeyCombo;
use openlogi_core::action::Action;

// 1. Parse user input into a platform-neutral combo
let combo: KeyCombo = "Cmd+Shift+P".parse().expect("valid shortcut format");

// 2. Wrap in a custom action for storage
let action = Action::CustomShortcut(combo);

// 3. Platform-specific injection (simplified)
#[cfg(target_os = "windows")]
fn inject_shortcut(combo: &KeyCombo) {
    // Dispatches via post_custom_shortcut in windows.rs
    openlogi_inject::inject::windows::post_custom_shortcut(combo);
}

#[cfg(target_os = "macos")]
fn inject_shortcut(combo: &KeyCombo) {
    // Uses macOS-specific synthesis path
    openlogi_inject::inject::macos::inject_combo(combo);
}

#[cfg(target_os = "linux")]
fn inject_shortcut(combo: &KeyCombo) {
    // Converts to Linux keycodes and emits events
    openlogi_inject::inject::linux::press_combo(combo);
}

```

## Text Input Handling in the Desktop UI

While shortcut injection handles system-level input, OpenLogi manages UI text input through GPUI-based components in the desktop crate. The design system defines consistent form controls in [[`crates/openlogi-desktop/src/ui/theme.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/ui/theme.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-desktop/src/ui/theme.rs), specifying dimensions and styling for text fields and buttons.

The primary interface for shortcut entry resides in [[`crates/openlogi-desktop/src/features/action_ring/editor.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/action_ring/editor.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-desktop/src/features/action_ring/editor.rs). This component renders a text input field where users type shortcut strings. The editor captures keystrokes, displays the raw string representation, and validates the input through `KeyCombo::parse` before persisting the action to the configuration store. This separation ensures that text input handling remains isolated from the injection pipeline, with the UI layer responsible only for data collection and the core handling execution.

## Summary

- **Neutral Representation**: The `KeyCombo` parser in [`key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/key_combo.rs) converts strings like `"Cmd+Shift+P"` into platform-agnostic structures.
- **Action Storage**: Shortcuts are stored as `Action::CustomShortcut` enums, serialized through TOML as shown in the core binding tests.
- **Platform Injection**: The `openlogi-inject` crate provides OS-specific implementations in [`windows.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/windows.rs), [`macos.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/macos.rs), and [`linux.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/linux.rs) that translate `KeyCombo` values to native events.
- **UI Text Input**: GPUI components in [`editor.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/editor.rs) and [`theme.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/theme.rs) handle configuration input, using `KeyCombo::parse` for validation before storage.
- **Error Handling**: Each platform module logs warnings when shortcuts cannot be mapped natively, such as held shortcuts lacking Windows support.

## Frequently Asked Questions

### How does OpenLogi parse a shortcut string entered by the user?

OpenLogi uses the `KeyCombo::parse` method implemented in [[`crates/openlogi-core/src/binding/key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/key_combo.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/key_combo.rs). This parser accepts human-readable strings containing modifiers (Cmd, Ctrl, Alt, Shift) and key names, normalizing them into a structured format that works across operating systems. The desktop UI invokes this parser in the action-ring editor to validate input before saving.

### What happens when a shortcut has no native mapping on the target OS?

The injection layer includes guard clauses that detect unsupported combinations. For example, if a held shortcut lacks a Windows equivalent, [[`crates/openlogi-inject/src/inject/windows.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject/windows.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-inject/src/inject/windows.rs) logs a warning and drops the event rather than attempting injection. This prevents system errors and alerts developers to platform-specific limitations in their shortcut configurations.

### How is text input captured for editing shortcut configurations?

The desktop application uses GPUI components defined in [[`crates/openlogi-desktop/src/features/action_ring/editor.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/action_ring/editor.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-desktop/src/features/action_ring/editor.rs) and styled according to [[`crates/openlogi-desktop/src/ui/theme.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/ui/theme.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-desktop/src/ui/theme.rs). These components provide text fields where users type shortcut strings, which the application then parses and validates using the core `KeyCombo` parser before persisting to the configuration file.

### Can custom shortcuts be persisted across application restarts?

Yes, OpenLogi serializes `Action::CustomShortcut` values to TOML configuration files. The serialization logic is tested in [[`crates/openlogi-core/src/binding/tests.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/tests.rs)](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/tests.rs), demonstrating that `KeyCombo` structures round-trip through text format without data loss. When the application launches, it reloads these definitions and makes them available for injection through the action-ring system.