How to Configure Button Remapping in OpenLogi: A Complete TOML Guide
OpenLogi stores button remappings in a TOML configuration file at ~/.config/openlogi/config.toml, using a hierarchical structure that supports global defaults and per-device overrides defined by HID++ button codes mapped to keyboard shortcuts, commands, or other actions.
OpenLogi is an open-source driver for Logitech HID++ devices that enables deep hardware customization through declarative configuration. The button remapping system is implemented in crates/openlogi-core/src/config.rs, which parses user-defined TOML tables into a Config struct containing a button_remap field that maps device identifiers to lists of input translations.
Configuration File Location
OpenLogi creates the configuration file at ~/.config/openlogi/config.toml by default on Linux and macOS systems. To verify the exact path on your system, run the openlogi --config-path command in your terminal.
The configuration is loaded once at agent startup. The parser validates the TOML structure and builds an internal lookup table that the HID++ driver uses to intercept button events and synthesize replacement inputs.
Global vs. Per-Device Remapping Hierarchy
The button_remap configuration uses a two-tier hierarchy that allows you to define universal defaults and device-specific exceptions:
- Global
[button_remap]– Applies to all connected Logitech devices unless overridden by a specific device entry - Device-specific
[[device.<device_id>.button_remap]]– Overrides or extends the global list for a specific vendor/product ID pair
When OpenLogi processes input events, it checks for device-specific mappings first. If no match exists, it falls back to the global configuration. This hierarchy is enforced in the configuration loader at crates/openlogi-core/src/config.rs.
Button Mapping Syntax
Each remapping entry within the TOML arrays requires specific fields that define the input interception and output action:
from– The HID++ button code to intercept (e.g.,button_5,button_8)to– The target action, which can be a key combination likeCtrl+Alt+T, a media key likemedia_play_pause, or a system action likemission_controlcondition(optional) – An application-specific filter that limits the remap to when a specific app is foregrounded, identified by bundle ID (macOS) or executable name
The parser in crates/openlogi-core/src/config.rs validates these fields and ensures that from values correspond to valid HID++ button constants before registering them with the platform-specific input subsystems.
Identifying Your Device ID
To configure per-device remappings, you must know your hardware's vendor ID (VID) and product ID (PID). OpenLogi provides a CLI command to discover these identifiers:
openlogi list
This command is implemented in crates/openlogi-cli/src/cmd/list.rs and outputs device strings in the format VID:PID (hexadecimal). Use this exact string in your TOML tables within the [[device."VID:PID".button_remap]] headers, such as [[device."046d:c539".button_remap]] for a Logitech G502 mouse.
Platform-Specific Permissions
Button remapping requires low-level input access that varies by operating system:
Linux – The OpenLogi agent needs write access to /dev/uinput to synthesize key events. The project repository includes a udev rule that grants this permission to users in the input group. Without this access, the remapping logic in the core crate cannot inject the translated events.
macOS – The agent uses the event-tap system to intercept and replace button inputs. You must grant "Accessibility" permissions to the OpenLogi binary in System Preferences > Security & Privacy > Privacy > Accessibility. The code handles the event-tap registration in the platform-specific device layers.
Reloading and Applying Changes
After editing config.toml, you must reload the configuration for changes to take effect:
openlogi reload
Alternatively, restart the OpenLogi agent (openlogi-agent). The reload command triggers the configuration parser to rebuild the button_remap lookup tables without restarting the underlying HID++ connection handlers.
Practical Configuration Examples
Here is a complete ~/.config/openlogi/config.toml demonstrating global and per-device remappings:
# Global button remapping – applies to every device
[button_remap]
from = "button_5"
to = "media_play_pause"
# Per-device remapping for Logitech G502 (VID:PID 046d:c539)
[[device."046d:c539".button_remap]]
from = "button_8"
to = "Ctrl+Alt+T"
# Per-device remapping for Logitech MX Master with app-specific condition
[[device."046d:b012".button_remap]]
from = "button_4"
to = "mission_control"
condition = { app = "com.google.Chrome" }
The first table defines a universal side-button remap. The subsequent arrays target specific hardware by their USB identifiers. For a comprehensive reference of all supported configuration options, see docs/config.example.toml in the repository root.
Summary
- OpenLogi reads button remappings from
~/.config/openlogi/config.toml, parsed bycrates/openlogi-core/src/config.rs - Use
[button_remap]for global defaults and[[device."VID:PID".button_remap]]for device-specific overrides - Each mapping requires
from(source button) andto(target action) fields, with an optionalconditionfor app-specific activation - Discover device IDs using
openlogi list(source:crates/openlogi-cli/src/cmd/list.rs) - Linux requires
/dev/uinputaccess via udev rules; macOS requires Accessibility permissions for event-tapping - Apply changes with
openlogi reloador by restarting the agent
Frequently Asked Questions
How do I find the correct button codes for my Logitech mouse?
Use the openlogi list command to display connected devices, then monitor the OpenLogi agent logs in debug mode. When you press physical buttons, the HID++ reports log the corresponding button codes (e.g., button_4, button_8) that you must use in the from field of your TOML configuration.
Can I remap buttons to launch specific applications rather than keyboard shortcuts?
Yes. The to field accepts command strings in addition to key combinations. You can specify a shell command such as to = "exec:firefox" or to = "exec:/usr/local/bin/myscript.sh" depending on your platform. The agent executes these commands via the system shell when the button event triggers.
Why aren't my button remaps working after editing the config file?
First, ensure you ran openlogi reload or restarted the agent. Then verify that the device ID in your TOML matches exactly (including case) with the output from openlogi list. Finally, check platform permissions: Linux users need write access to /dev/uinput, and macOS users must grant Accessibility permissions to the OpenLogi binary in System Security settings.
Does OpenLogi support conditional remapping based on the active application?
Yes. Add a condition table to any mapping entry with an app field specifying the bundle identifier (macOS) or executable name (Linux). For example, condition = { app = "com.apple.Terminal" } restricts the remap to only activate when Terminal is the foreground application.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →