# OpenLogi TOML Configuration File Structure: Complete Schema Guide

> Explore the OpenLogi TOML configuration file structure. Understand the schema, app settings, devices, keyboard, and more with this complete guide for AprilNEA/OpenLogi.

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

---

**OpenLogi stores all user preferences in a single versioned TOML file structured around a top-level `Config` struct with five primary sections: `schema_version`, `app_settings`, `selected_device`, `devices`, and `keyboard`, where the `devices` map uses stable physical identifiers as keys and supports nested configuration for DPI, gestures, lighting, and host switching.**

OpenLogi is an open-source input device manager that persists settings in a flat TOML document rather than a database or JSON store. Understanding the precise structure of the OpenLogi TOML configuration file allows you to customize device behavior programmatically, version-control your setup, and deploy consistent configurations across multiple workstations. The configuration schema is defined in the Rust source at [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs) within the AprilNEA/OpenLogi repository.

## Schema Version and Top-Level Structure

The configuration root requires a `schema_version` field to ensure backward compatibility.

According to the source code in [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs) (lines 63-94), the `Config` struct comprises the following top-level keys:

- **`schema_version`** — An integer identifying the config schema format. The current version is `4`.
- **`app_settings`** — A table containing global preferences such as `launch_at_login`, `check_for_updates`, `language`, `thumbwheel_sensitivity`, and `appearance` (defined in the `AppSettings` struct).
- **`selected_device`** — An optional string specifying which device should be active on startup (e.g., `"receiver:abc123:slot:1"`).
- **`devices`** — A map where each key is a stable physical-device identifier and each value is a device-specific configuration table.
- **`keyboard`** — A table containing global keyboard shortcuts that apply across all connected keyboards.

A minimal valid configuration requires only the schema version and optional app settings:

```toml
schema_version = 4

[app_settings]
launch_at_login = true
language = "en"

```

## Device-Level Configuration Structure

The `devices` table is the most complex section, using physical device identifiers as keys (format: `receiver:<ID>:slot:<N>`). Each device entry supports multiple nested sub-tables defined in the configuration source.

### DPI, Scroll, and Sensitivity Settings

Configure pointer speed and scrolling behavior under each device key:

- **`dpi`** — Integer value (e.g., `1600`).
- **`dpi_presets`** — Array of integers for quick-switching (e.g., `[800, 1600, 3200]`).
- **`thumbwheel_sensitivity`** — Numeric sensitivity scalar.
- **`invert_scroll`** — Boolean to reverse scroll direction.
- **`scroll_resolution`** — String enum: `"high"` or `"low"`.

Example:

```toml
[devices."receiver:abcd1234:slot:1"]
dpi = 1600
dpi_presets = [800, 1600, 3200]
invert_scroll = false

```

### Button and Gesture Bindings

Define input mappings in the `bindings` sub-table:

- **Standard buttons** — Map identifiers like `Back`, `Forward` to actions like `BrowserBack`, `MissionControl`.
- **Gesture button** — Special sub-table `GestureButton` maps `Click`, `Up`, `Down`, `Left`, `Right` directions to actions.

```toml
[devices."receiver:abcd1234:slot:1".bindings]
Back = "BrowserBack"
Forward = "BrowserForward"

[devices."receiver:abcd1234:slot:1".bindings.GestureButton]
Up = "MissionControl"
Down = "AppExpose"

```

### Per-Application Overrides

Use `per_app_bindings` to override global bindings when specific applications are active:

```toml
[devices."receiver:abcd1234:slot:1".per_app_bindings."com.example.App"]
Back = "CustomAction"

```

### Advanced Device Features

Additional optional sub-tables include:

- **`action_ring`** — Configure the radial menu with `enabled`, `haptics`, and `default.slots` (each slot containing `action` and `icon`).
- **`lighting`** — RGB control via `enabled`, `color`, and `brightness`.
- **`smartshift`** — Ratchet mode configuration with `mode`, `auto_disengage`, and `tunable_torque`.
- **`host_switch_targets`** — Array of device identifiers for host-switching capabilities.
- **`fn_lock`** — Boolean toggle for function-key lock state.

## Global Keyboard Bindings

The `keyboard` table defines shortcuts that are not tied to any specific pointing device but apply to connected keyboards:

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

```

This configuration resides in the `KeyboardConfig` definition within [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs).

## Loading the Configuration Programmatically

When building integrations or automated setup scripts, you can load and validate the TOML file using the core library:

```rust
use openlogi_core::config::Config;

let cfg = Config::load_from_path("/home/user/.config/openlogi/config.toml")?;
println!("Loaded {} device(s)", cfg.devices.len());

```

This method parses the entire schema, validates the `schema_version`, and deserializes all nested device configurations according to the structs defined in the source.

## Summary

- OpenLogi uses a single, flat TOML file versioned with `schema_version` (currently `4`).
- The root schema includes `app_settings`, `selected_device`, `devices`, and `keyboard` tables.
- Device configurations are keyed by stable physical identifiers (e.g., `receiver:abc123:slot:2`) and support DPI presets, button remapping, gesture controls, per-app bindings, action rings, lighting, and SmartShift settings.
- Global keyboard shortcuts are defined separately in the `keyboard.bindings` table.
- The complete schema is implemented in [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs) with a canonical example provided in [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml).

## Frequently Asked Questions

### Where is the OpenLogi TOML configuration file located on disk?

By default, OpenLogi loads the configuration from the system-specific user config directory, typically `~/.config/openlogi/config.toml` on Linux or the equivalent platform-specific path on macOS and Windows. The application creates this file automatically if it does not exist, populating it with default values and the current `schema_version`.

### What happens if my config file uses an outdated schema version?

OpenLogi checks the `schema_version` field when loading [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs). If the version is older than the expected current version (4), the application may attempt automatic migration or refuse to load the file to prevent data corruption. You should back up your configuration before upgrading the application and consult the [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml) file to identify schema changes.

### How do I configure per-application button mappings for specific devices?

Under any device entry in the `devices` table, create a `per_app_bindings` sub-table keyed by the application's bundle identifier (e.g., `com.example.App`). Within this table, map button names to actions exactly as you would in the top-level `bindings` table. These mappings override the global device bindings only when the specified application is frontmost.

### Can I define global keyboard shortcuts that aren't associated with any mouse or trackpad?

Yes. The `keyboard` table at the root level contains a `bindings` sub-table where you can define shortcuts using keys like `f1` or chord combinations like `"shift+command+f5"`. These bindings are processed by the `KeyboardConfig` struct independently of the `devices` map and apply to any compatible keyboard connected to the system.