How to Configure Per-Application Profiles in OpenLogi: A Complete Guide

Configure per-application profiles in OpenLogi by editing the config.toml file to define app-specific button bindings and Actions-Ring layouts using bundle IDs, WM classes, or executable paths as keys.

OpenLogi supports sophisticated per-application customization that lets you override global button bindings and Actions-Ring layouts when specific apps are in the foreground. These profiles are stored in the central TOML configuration file that both the GUI and background agent consume. Understanding how to structure these overrides allows you to create context-aware workflows for any supported Logitech device.

Locate the Configuration File

OpenLogi stores all per-application settings in a single config.toml file. The default location varies by platform:

  • macOS / Linux: ~/.config/openlogi/config.toml
  • Windows: %USERPROFILE%\.config\openlogi\config.toml

You can also open this file directly from the GUI by navigating to Settings → Open Config. Both the desktop application and the background agent read from this file, ensuring your per-application profiles remain synchronized across the system.

Identify the Application Identifier

Before configuring profiles, you must determine the correct application key for your target software. OpenLogi uses different identification methods depending on the operating system:

  • macOS: Use the app's bundle identifier, such as com.microsoft.VSCode or org.mozilla.firefox.
  • Linux (X11 / Wayland): The system reads the X11 WM_CLASS property. Note that on Wayland, you need XWayland for per-app profile switching to function correctly, as documented in the installation notes.
  • Windows: Use the exact lower-cased executable path or the shortcut format exe:<filename>.exe.

The identifier serves as the key in the per_app_bindings and action_ring.apps maps defined in crates/openlogi-core/src/config/device.rs.

Set Up Per-Application Button Bindings

Per-application bindings override the global bindings table when the specified app is active. Inside your device configuration table, create a per_app_bindings sub-table keyed by the app identifier.

The underlying structure in DeviceConfig::per_app_bindings is defined as BTreeMap<String, BTreeMap<ButtonId, Action>>, mapping application identifiers to button-to-action pairs.

Here is a complete example for a Logitech mouse with the device key receiver:12345:slot:1:

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

# Global bindings used as fallback

bindings = { Button5 = "Back", Button6 = "Forward" }

# Per-application overrides for VS Code

[devices."receiver:12345:slot:1".per_app_bindings."com.microsoft.VSCode"]
Button5 = "Copy"
Button6 = "Paste"

# Per-application overrides for Firefox

[devices."receiver:12345:slot:1".per_app_bindings."org.mozilla.firefox"]
Button5 = "Back"
Button6 = "Forward"

When Visual Studio Code is the foreground window, Button5 triggers Copy instead of Back. The GUI can edit these entries via Device → Per-App Bindings, writing changes atomically back to config.toml.

Configure Per-Application Actions-Ring Layouts

Beyond button remapping, you can define a complete eight-slot Actions-Ring layout for each application. The DeviceConfig::action_ring field accepts an ActionRingConfig that supports per-app customization through an apps sub-table.

The global ring serves as the default, while entries under action_ring.apps take precedence when the corresponding application is focused:

[devices."receiver:12345:slot:1".action_ring]

# Global ring layout (fallback)

Top = { action = "Copy", icon = "Keyboard" }
Bottom = { action = "Paste", icon = "Keyboard" }

# VS Code specific ring

[devices."receiver:12345:slot:1".action_ring.apps."com.microsoft.VSCode"]
Top = { action = "ShowTerminal", icon = "Terminal" }
Bottom = { action = "ShowExplorer", icon = "Folder" }

# Firefox specific ring

[devices."receiver:12345:slot:1".action_ring.apps."org.mozilla.firefox"]
Top = { action = "Back", icon = "ArrowLeft" }
Bottom = { action = "Forward", icon = "ArrowRight" }

When the foreground application matches one of the keys in action_ring.apps, OpenLogi renders that specific layout; otherwise, it falls back to the global configuration defined in the base action_ring table.

Apply and Verify Changes

After editing config.toml, you must ensure the running agent recognizes the new profiles:

  1. Reload the configuration: The GUI automatically reloads when you save the file. For manual edits, reopen the GUI or select Reload Config from the tray menu so the agent picks up changes.
  2. Verify active profile: Switch to your target application, then trigger the Actions-Ring using your configured shortcut. Confirm the per-app layout appears rather than the global default.
  3. Test button overrides: Press a button you remapped in per_app_bindings and verify the specific action fires instead of the global binding.

If the profile fails to activate, double-check the application identifier against the requirements in the previous section and ensure the key exists in the TOML map.

Summary

  • Per-application profiles in OpenLogi are stored in config.toml and interpreted by both the GUI and background agent.
  • Application keys use macOS bundle IDs, Linux WM_CLASS strings, or Windows executable paths.
  • Button overrides are defined in the per_app_bindings map within each device table, as implemented in crates/openlogi-core/src/config/device.rs.
  • Actions-Ring layouts support per-app customization via the action_ring.apps sub-table, falling back to global settings when no match exists.
  • Changes apply immediately when edited through the GUI, or require a manual reload when editing config.toml directly.

Frequently Asked Questions

Why isn't my per-application profile activating on Linux Wayland?

Wayland does not expose window class information in the same manner as X11. OpenLogi relies on the X11 WM_CLASS property to identify foreground applications, so you must run your applications under XWayland for per-app profile switching to function. This limitation is documented in docs/INSTALL-linux.md.

Can I use the GUI to create per-application profiles instead of editing TOML?

Yes. The OpenLogi GUI provides a Device → Per-App Bindings interface that writes to the same config.toml file atomically. However, understanding the raw TOML structure is essential for manual backups, version control, or complex configurations involving multiple applications.

What happens if an application matches both global and per-app bindings?

Per-app bindings always take precedence. When the foreground application matches a key in per_app_bindings, OpenLogi uses that specific action map. If no match exists, the system falls back to the global bindings table defined at the device level.

How do I find the bundle ID for a macOS application?

You can locate the bundle identifier by right-clicking the app in Finder, selecting Show Package Contents, and opening Contents/Info.plist to find the CFBundleIdentifier key. Alternatively, run osascript -e 'id of app "Application Name"' in Terminal to retrieve the identifier directly.

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 →