# How to Define Custom Shortcuts in OpenLogi TOML Configuration

> Learn how to define custom shortcuts in OpenLogi TOML configuration. Easily set key combos like Cmd+Shift+P for your actions.

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

---

**OpenLogi stores custom shortcuts in a TOML configuration file using the `CustomShortcut` variant of the `Action` enum, which accepts a `KeyCombo` string formatted as modifier-key combinations like `"Cmd+Shift+P"`.**

OpenLogi is an open-source input device manager that allows users to remap hardware buttons and create complex keyboard shortcuts through TOML configuration files. Defining **custom shortcuts** requires understanding how the application parses key combinations using the `KeyCombo` parser and binds them to specific contexts.

## Understanding the CustomShortcut Action Type

In the OpenLogi source code, custom shortcuts are represented by the **`CustomShortcut`** variant of the `Action` enum defined in [`crates/openlogi-core/src/binding/action.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/action.rs) [L48-L56](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/action.rs#L48-L56). This variant wraps a `KeyCombo` struct that stores parsed representations of keyboard chords.

The `KeyCombo` parser lives in [`crates/openlogi-core/src/binding/key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/key_combo.rs). When parsing shortcut strings, the `KeyCombo::from_str` implementation [L235-L255](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/key_combo.rs#L235-L255) uses helper functions `parse_modifier` and `parse_key` to validate each token. The parser strictly enforces format rules: it rejects empty strings, missing keys, multiple non-modifier keys, or unknown tokens.

## TOML Syntax for Custom Shortcuts

Custom shortcuts can be bound at three different scope levels in your OpenLogi configuration file.

### Device-Level Button Bindings

Target specific hardware buttons by referencing the device receiver ID and slot number under the `[devices]` table:

```toml
[devices."receiver:aabbccdd:slot:1".bindings]

# Replace middle click with F1 key

MiddleClick = { CustomShortcut = "F1" }

# Map a complex chord to a mouse button

SomeButton = { CustomShortcut = "Cmd+Ctrl+Alt+Esc" }

```

### Per-Application Context Bindings

Create context-sensitive shortcuts that only activate when a specific application is focused:

```toml
[devices."receiver:aabbccdd:slot:1".per_app_bindings."com.microsoft.VSCode"]

# Send Command Palette shortcut when pressing Back button in VS Code

Back = { CustomShortcut = "Cmd+Shift+P" }

```

### Global Keyboard Bindings

Define system-wide hotkeys in the `[keyboard.bindings]` section:

```toml
[keyboard.bindings]

# Global hotkey to show desktop

"shift+command+f5" = "ShowDesktop"

```

## Key Combo Format Specification

OpenLogi expects shortcut strings to follow a strict `modifier+key` syntax using `+` as the separator.

### Supported Modifier Tokens

The parser recognizes multiple aliases for common modifiers:

- **Command key**: `Cmd`, `Command`, `Meta`, or `Win`
- **Control**: `Ctrl` or `Control`
- **Alt/Option**: `Alt` or `Option`
- **Shift**: `Shift`

### Validation Rules

According to the `KeyCombo` implementation in [`key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/key_combo.rs), the parser enforces these constraints:

- **Empty strings** are rejected immediately
- **Multiple non-modifier keys** result in a parsing error (only one final key allowed)
- **Missing key tokens** cause validation failure
- **Unknown tokens** trigger an error rather than being silently ignored

The `+` separator must appear between every token, with modifiers preceding the final key.

## Implementation Examples

The following patterns from [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml) illustrate practical usage:

| Binding Context | TOML Syntax | Result |
|-----------------|-------------|---------|
| Device button replacement | `MiddleClick = { CustomShortcut = "F1" }` | Sends F1 keystroke when middle mouse button is pressed |
| IDE-specific shortcut | `Back = { CustomShortcut = "Cmd+Shift+P" }` | Opens Command Palette in VS Code |
| Complex modifier chord | `SomeButton = { CustomShortcut = "Cmd+Ctrl+Alt+Esc" }` | Synthesizes Command+Control+Option+Escape |
| Global system hotkey | `"shift+command+f5" = "ShowDesktop"` | Shows desktop when global chord is pressed |

## Testing and Validation

OpenLogi includes round-trip tests in [`crates/openlogi-core/src/binding/tests.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/tests.rs) [L96-L99](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/binding/tests.rs#L96-L99) that verify custom shortcuts serialize to TOML and deserialize back to equivalent `KeyCombo` structures without data loss.

After editing your configuration file, save the changes and restart OpenLogi (or trigger a config reload). The application validates the TOML structure on startup and logs any parsing errors for malformed shortcut strings.

## Summary

- OpenLogi defines custom shortcuts using the **`CustomShortcut`** variant of the `Action` enum, which wraps a **`KeyCombo`** struct.
- Shortcut strings use **`+`**-separated tokens with modifiers (`Cmd`, `Ctrl`, `Alt`, `Shift`) preceding a single non-modifier key.
- Bindings can be defined at three scopes: **device-level**, **per-application**, and **global keyboard** configurations.
- The parser in [`key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/key_combo.rs) enforces strict validation, rejecting empty strings, unknown tokens, or multiple final keys.
- Changes require saving the TOML file and restarting the application to take effect.

## Frequently Asked Questions

### What is the correct format for modifier keys in OpenLogi TOML?

OpenLogi accepts multiple aliases for modifier keys. You can use `Cmd`, `Command`, `Meta`, or `Win` for the command key; `Ctrl` or `Control` for the control key; and `Alt` or `Option` for the option/alt key. Always place modifiers before the final key and separate them with plus signs, such as `"Cmd+Shift+P"`.

### Why does OpenLogi reject my custom shortcut string?

The `KeyCombo::from_str` parser in [`crates/openlogi-core/src/binding/key_combo.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/key_combo.rs) rejects strings that contain empty values, multiple non-modifier keys, or unrecognized tokens. Ensure your string contains valid modifier aliases followed by exactly one final key character, with no trailing plus signs or spaces.

### How do I apply changes after editing the TOML configuration file?

After defining your custom shortcuts in the TOML file, save the file and restart the OpenLogi application. The configuration loader validates the structure on startup, and the new shortcuts become active immediately after initialization.

### Can I use custom shortcuts for per-application button remapping?

Yes. OpenLogi supports context-aware bindings under the `per_app_bindings` table. Specify the application bundle identifier (such as `com.microsoft.VSCode`) and assign `CustomShortcut` values to hardware buttons that will only trigger when that application is focused.