# How to Configure Global Keyboard Remapping in OpenLogi: Complete Guide

> Learn how to configure global keyboard remapping in OpenLogi by editing the TOML config. Map key triggers to actions and commit changes easily for personalized control.

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

---

**Global keyboard remapping in OpenLogi is configured by editing the `[keyboard.bindings]` table in the application's TOML configuration file, where key triggers map to actions defined in [`openlogi-core/src/binding.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/openlogi-core/src/binding.rs), and changes are committed through `AppState::commit_keyboard_binding`.**

OpenLogi's desktop client provides a unified way to remap function keys across all connected Logitech devices. Unlike per-device bindings stored under `config.devices`, **global keyboard bindings** apply universally and persist through the `AppState` management layer. This article explains the configuration schema, source code implementation, and both manual and programmatic approaches to customization.

---

## Configuration File Location and Structure

OpenLogi stores user settings in a TOML file, typically located at `~/.config/openlogi/config.toml` on Linux or equivalent platform-specific paths. The global keyboard remapping section lives at the top level of this file, separate from device-specific configurations.

| File | Purpose |
|------|---------|
| [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml) | Complete reference showing valid `keyboard.bindings` syntax |
| [`crates/openlogi-desktop/src/features/keyboard/mod.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/keyboard/mod.rs) | UI module declaring global scope of keyboard bindings |
| [`crates/openlogi-desktop/src/features/keyboard/function_row.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/keyboard/function_row.rs) | Visual editor implementation for key selection |
| [`crates/openlogi-core/src/binding.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding.rs) | `Action` enum defining all assignable actions |

The `[keyboard.bindings]` table uses **key trigger strings** as keys and **action values** that deserialize into `openlogi_core::binding::Action`.

---

## TOML Configuration Syntax

### Basic Key-to-Action Mapping

Simple bindings use unquoted key names for single keys or quoted strings for combinations with modifiers:

```toml
[keyboard.bindings]
f1 = "MissionControl"
f2 = "ShowDesktop"
f3 = "Launchpad"
"shift+command+f5" = "ScreenSaver"

```

### Supported Key Trigger Formats

- **Simple keys**: `f1`, `f2`, `escape`, `space`, `tab`
- **Modifier combinations**: `shift+f1`, `command+space`, `"ctrl+alt+delete"` (quoted when containing `+`)
- **Multiple modifiers**: `shift+command+f5`, `ctrl+shift+alt+t`

### Complex Action Types

Beyond simple string actions, OpenLogi supports structured action definitions for advanced use cases:

```toml
[keyboard.bindings]

# Custom shortcut executed on key hold

f9 = { HoldShortcut = "Ctrl+Space" }

# Application launcher with metadata

f10 = { OpenApplication = { path = "/Applications/iTerm.app", display_name = "Terminal" } }

```

Available actions are defined in [`crates/openlogi-core/src/binding.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding.rs) as the `Action` enum, including variants like `MissionControl`, `ShowDesktop`, `Launchpad`, `ScreenSaver`, `HoldShortcut`, `OpenApplication`, and `CustomShortcut`.

---

## Using the Function-Row UI

The desktop client provides a visual editor accessible through the **Function-Row view**, implemented in [`crates/openlogi-desktop/src/features/keyboard/function_row.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/keyboard/function_row.rs).

The UI workflow:

1. Renders a graphical keyboard layout with interactive key hotspots
2. Captures click events on function keys (F1-F12 and beyond)
3. Displays an action picker populated from `openlogi_core::binding::Action` variants
4. Calls `AppState::commit_keyboard_binding` when a selection is confirmed

This method automatically validates against supported key triggers and action types, preventing malformed configurations.

---

## Programmatic Configuration with `commit_keyboard_binding`

For automation or CLI tooling, modify bindings directly through the same API the UI uses:

```rust
use openlogi_core::binding::{Action, KeyTrigger};
use openlogi_desktop::state::AppState;
use std::str::FromStr;

fn add_global_binding() {
    // Access the global application state
    let app_state = AppState::global();
    
    // Parse key trigger from string representation
    let trigger = KeyTrigger::from_str("F4")
        .expect("Valid key trigger");
    
    // Select action from the core enum
    let action = Action::MissionControl;
    
    // Commit and persist the binding
    app_state.commit_keyboard_binding(trigger, action);
}

```

The `commit_keyboard_binding` method in [`crates/openlogi-desktop/src/state.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/state.rs) performs three operations:

1. Updates the in-memory `AppState.config.keyboard.bindings` HashMap
2. Marks the configuration as dirty for dirty-tracking purposes
3. Serializes and writes the complete config back to the TOML file on disk

---

## Source Code References

Key implementation details from the repository:

- **Binding definitions**: [`crates/openlogi-core/src/binding.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding.rs) — contains the `Action` enum with all supported keyboard actions
- **State management**: `crates/openlogi-desktop/src/state/` — houses `AppState` struct and persistence logic
- **UI implementation**: [`crates/openlogi-desktop/src/features/keyboard/function_row.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/keyboard/function_row.rs) — the `FunctionRowView` component that bridges user interaction to `commit_keyboard_binding`
- **Example configuration**: [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml) — authoritative reference for valid TOML syntax

---

## Summary

- **Global keyboard remapping** lives in the `[keyboard.bindings]` table of OpenLogi's TOML config, distinct from per-device bindings
- **Key triggers** support simple names and modifier-rich quoted strings; **actions** are type-safe variants from `openlogi_core::binding::Action`
- **Visual editing** is available through the Function-Row view, which validates and commits via `AppState::commit_keyboard_binding`
- **Programmatic changes** use the same `commit_keyboard_binding` API, ensuring consistency between UI and automation workflows

---

## Frequently Asked Questions

### What is the difference between global keyboard bindings and device-specific bindings?

Global keyboard bindings under `[keyboard.bindings]` apply to all connected Logitech keyboards universally, while device-specific bindings under `config.devices[<id>].bindings` are scoped to individual hardware. The global configuration takes precedence when no device-specific override exists, and it is the recommended approach for function-key remapping that should remain consistent across multiple devices.

### Can I use modifier combinations like Ctrl+Shift+F1 in global keyboard remapping?

Yes. Modifier combinations are supported by quoting the key trigger string in TOML, such as `"ctrl+shift+f1" = "MissionControl"`. The `KeyTrigger` type in `openlogi-core` parses these strings during deserialization, supporting any combination of `shift`, `ctrl`, `alt`, `command`, and `super` modifiers combined with standard key names.

### Where is the configuration file stored on different platforms?

The configuration file follows platform conventions: `~/.config/openlogi/config.toml` on Linux, `~/Library/Application Support/openlogi/config.toml` on macOS, and `%APPDATA%\openlogi\config.toml` on Windows. The exact path can be verified at runtime through OpenLogi's settings panel or by checking the logs at application startup, which emit the resolved configuration directory.