OpenLogi TOML Configuration File Structure: Complete Schema Guide

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 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 (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:

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:

[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.
[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:

[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:

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

This configuration resides in the KeyboardConfig definition within 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:

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 with a canonical example provided in 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. 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 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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →