How to Configure Per-Application Action Ring Layouts in OpenLogi

OpenLogi allows you to override the global Action Ring layout on a per-application basis by defining per_app_bindings sections in your TOML configuration file, using either process names or bundle identifiers to trigger application-specific slot configurations.

OpenLogi is an open-source input device manager that enables advanced customization of Logitech HID++ devices. When you configure per-application action ring layouts in OpenLogi, the software automatically switches between different button mappings whenever you change foreground applications, providing context-sensitive control schemes tailored to your workflow.

Understanding the Configuration Hierarchy

OpenLogi stores user configuration in a TOML file located at $HOME/.config/openlogi/config.toml. The configuration uses a hierarchical structure organized by physical devices and slots.

Each device is identified by a receiver serial number and slot number pair, formatted as receiver:<serial>:slot:<n>. Within each device section, you can define both global defaults and application-specific overrides.

The configuration hierarchy follows this pattern:


[devices."receiver:<serial>:slot:<n>"]                            # Device root

[devices."receiver:<serial>:slot:<n>".action_ring]                  # Global layout

default.slots = ["action1", "action2", ...]                        # 8 required slots

[devices."receiver:<serial>:slot:<n>".per_app_bindings."<app-id>"]  # App-specific

action_ring = { slots = ["app-action1", ...] }                     # Override layout

Defining Global vs. Per-Application Action Rings

The global Action Ring serves as the default layout when no specific application binding matches the current foreground window. You define this using the action_ring.default.slots array, which must contain exactly eight action entries.

Per-application bindings override this global layout when specific conditions are met. The <app-id> key identifies target applications using one of two formats:

  • Process name format: exe:sharex.exe for Windows executables
  • Bundle identifier format: com.microsoft.VSCode for macOS and Linux applications

When the foreground application changes, OpenLogi's desktop process queries the current window, matches it against the per_app_bindings table, and activates the corresponding ring layout.

Step-by-Step Configuration Examples

Linux and macOS Application Bundles

To configure a per-application layout for Visual Studio Code on macOS or Linux, identify the bundle identifier and create a nested configuration section:

[devices."receiver:aabbccdd:slot:1"]

# Global default layout

[devices."receiver:aabbccdd:slot:1".action_ring]
default.slots = [
    "Zoom", "Scroll", "DPI+", "DPI-", "Button1", "Button2", "Button3", "Button4"
]

# Per-application override for VS Code

[devices."receiver:aabbccdd:slot:1".per_app_bindings."com.microsoft.VSCode"]
action_ring = { slots = [
    "Button5", "Button6", "Zoom", "Scroll", "DPI+", "DPI-", "Button1", "Button2"
] }

Windows Executable Names

For Windows applications, use the exe: prefix followed by the executable filename. This example configures ShareX with a customized action set:

[devices."receiver:11223344:slot:2".per_app_bindings."exe:sharex.exe"]
action_ring = { slots = [
    "Button3", "Button4", "Button5", "Button6", "Zoom", "Scroll", "DPI+", "DPI-"
] }

After saving your configuration file, restart OpenLogi or execute openlogi reload to apply the changes without restarting the system service.

How the Configuration is Applied

According to the OpenLogi source code, the per-application ring configuration flows through several specialized crates:

  1. Parsing: The openlogi-core crate reads the TOML file in crates/openlogi-core/src/config.rs, deserializing the configuration into DeviceConfig structs that contain ActionRingConfig and PerAppBinding definitions.

  2. Resolution: When the foreground application changes, openlogi-desktop (specifically in crates/openlogi-desktop/src/features/profiles.rs) performs the lookup against per_app_bindings using the current window's identifier.

  3. Communication: The desktop process transmits the new ring layout to the agent process via the IPC contract defined in crates/openlogi-ipc/src/ipc.rs.

  4. Device Programming: The agent receives the configuration in crates/openlogi-agent/src/server.rs and programs the HID++ device hardware with the new slot assignments.

  5. UI Rendering: Simultaneously, crates/openlogi-overlay/src/ring.rs renders the on-screen Action Ring display to reflect the current active layout.

Summary

  • OpenLogi uses a TOML configuration file at $HOME/.config/openlogi/config.toml to store device settings.
  • Per-application action rings are defined under [devices."receiver:<serial>:slot:<n>".per_app_bindings."<app-id>"] sections.
  • Application identifiers use either exe:filename.exe for Windows or bundle identifiers like com.company.App for Unix systems.
  • Each action_ring.slots array must contain exactly eight action entries to match the hardware's physical ring capacity.
  • Changes require a configuration reload or service restart to take effect.
  • The implementation spans multiple crates: openlogi-core for parsing, openlogi-desktop for window detection, openlogi-ipc for process communication, and openlogi-agent for hardware programming.

Frequently Asked Questions

How does OpenLogi identify applications for per-app bindings?

OpenLogi supports two identification methods based on the operating system. On Windows, use the exe: prefix followed by the executable name (e.g., exe:photoshop.exe). On macOS and Linux, use the application's bundle identifier (e.g., com.adobe.Photoshop). This matching occurs in crates/openlogi-desktop/src/features/profiles.rs, which queries the active window manager to retrieve the current foreground process identifier.

Can I mix different action types in the same ring layout?

Yes, the slots array accepts any valid OpenLogi action identifiers. Common actions include Scroll, Zoom, DPI+, DPI-, and various Button# mappings. You can combine these freely within the eight-slot array to create context-specific workflows, such as assigning zoom controls to graphic design applications while reserving media controls for video players.

What happens if the foreground application has no specific binding configured?

When no matching entry exists in the per_app_bindings table for the current foreground application, OpenLogi falls back to the global configuration specified in action_ring.default.slots. This ensures that devices always maintain a functional layout even when switching to applications without custom profiles.

How many per-application bindings can I define for a single device?

There is no explicit limit enforced by the configuration parser in crates/openlogi-core/src/config.rs. You can define as many per_app_bindings entries as needed within a single device section, allowing you to create distinct layouts for every application in your workflow. Each binding exists as a separate table entry under the device section's per_app_bindings namespace.

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 →