# How to Configure Per-Application Profile Bindings in OpenLogi: A Complete Guide

> Master per-application profile bindings in OpenLogi. Learn how to configure custom button mappings for specific apps with this comprehensive guide and override global settings.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-09-03

---

**OpenLogi implements per-application profile bindings as configuration overlays that override global button mappings when specific applications are in focus, using a nested TOML structure under `per_app_bindings` in [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml).**

OpenLogi is an open-source input device management system that enables context-aware button customization across different applications. Learning how to configure per-application profile bindings in OpenLogi allows you to create powerful workflows where identical physical buttons execute different actions depending on which software window is currently active.

## How Per-Application Bindings Work in OpenLogi

According to the OpenLogi source code, per-application bindings function as **overlays** that sit on top of global device configurations. In [`crates/openlogi-core/src/config/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config/device.rs), the system defines this structure at lines 90-97:

```rust
pub per_app_bindings: BTreeMap<String, BTreeMap<ButtonId, Action>>,

```

The outer map uses **application identifiers** as keys (macOS bundle IDs, Linux WM_CLASS values, or Windows executable paths), while the inner map associates **ButtonId** values with specific **Action** variants. When the agent running at [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs) (lines 553-604) loads the configuration, it builds an in-memory overlay. During button event processing, if the foreground application matches an overlay key, the specific action replaces the global binding.

## Locating Your Configuration File

Before adding per-application bindings, locate your [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) file:

- **macOS / Linux**: `$XDG_CONFIG_HOME/openlogi/config.toml` (typically `~/.config/openlogi/config.toml`)
- **Windows**: `%USERPROFILE%\.config\openlogi\config.toml`

The GUI writes to this file atomically, and the agent reloads changes automatically when possible.

## Step-by-Step Configuration Process

Follow these steps to configure per-application profile bindings in OpenLogi:

### 1. Identify Your Device Key

Each device is indexed by a **physical device key** (e.g., `"receiver:12345:slot:1"`). Open the OpenLogi GUI, select your device, and copy the key from the Device panel header.

### 2. Determine the Application Identifier

The overlay key must match your platform's application identification format:

- **macOS**: Use the bundle identifier (e.g., `com.microsoft.VSCode`)
- **Linux**: Use the X11/Wayland WM_CLASS string (e.g., `org.gnome.Terminal`). Note that Wayland sessions require XWayland for application detection as noted in [`docs/INSTALL-linux.md`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/INSTALL-linux.md).
- **Windows**: Use the full lower-cased executable path or the shortcut `exe:<filename>.exe` (e.g., `exe:chrome.exe`)

The GUI's Profile selector displays previously detected applications to ensure you use valid identifiers.

### 3. Add the Overlay to config.toml

Inside your device configuration, create a sub-table for the target application:

```toml
[devices."receiver:12345:slot:1".per_app_bindings."com.microsoft.VSCode"]

```

### 4. Map Buttons to Actions

Use button numbers from the GUI's Buttons panel as keys. Assign simple action names for immediate triggers, or use inline tables for short/long-press combinations:

```toml

# Simple actions

1 = "Copy"
2 = "Paste"

# Short/long press pair

3 = { short = "Undo", long = "Redo" }

```

### 5. Save and Verify

Save the [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) file. If edited while the GUI is open, restart the GUI or agent to pick up changes. Focus the target application and press the configured buttons to verify the actions fire correctly. You can also run `openlogi list` to inspect current per-app bindings for a device.

## Complete Configuration Example

Here is a complete TOML snippet demonstrating global bindings with per-application overlays:

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

# Global fallback bindings

1 = "ShowDesktop"
2 = "MissionControl"

# VS Code overlay

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

# Terminal overlay (Linux)

[devices."receiver:12345:slot:1".per_app_bindings."org.gnome.Terminal"]
3 = { short = "SplitHorizontally", long = "SplitVertically" }

```

## Platform-Specific Identifier Details

**macOS**: The system reports bundle identifiers such as `com.apple.Safari` or `com.microsoft.VSCode`. These are case-sensitive and must match exactly.

**Linux**: OpenLogi reads the `WM_CLASS` property through X11 protocols. On Wayland compositors, XWayland must be running to provide this metadata.

**Windows**: You may specify either the full absolute path to the executable in lowercase, or use the convenience prefix `exe:` followed by the filename (e.g., `exe:code.exe`).

## Summary

- OpenLogi stores per-application bindings as **overlays** in [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) under the `per_app_bindings` field defined in [`crates/openlogi-core/src/config/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config/device.rs).
- The system uses **platform-specific identifiers**: bundle IDs on macOS, WM_CLASS on Linux, and executable paths on Windows.
- Configuration follows a nested TOML structure: `[devices."<device-key>".per_app_bindings."<app-id>"]`.
- Actions support both simple strings and complex inline tables for short/long-press behaviors as documented in [`docs/CONFIGURATION.md`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/CONFIGURATION.md).
- Changes require a GUI or agent restart if edited while the application is running.

## Frequently Asked Questions

### Why aren't my per-application bindings working on Wayland?

Wayland sessions require XWayland for application window detection because OpenLogi reads the WM_CLASS property through X11 protocols. Ensure your Wayland compositor is running XWayland, or the agent cannot identify foreground applications to trigger overlays.

### Can I use the same button for different actions in different applications?

Yes. The overlay system in [`crates/openlogi-core/src/config/device.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config/device.rs) allows the same ButtonId to map to different Action variants in different application contexts. The agent resolves which action to fire based on the current foreground window at the time of the button press.

### How do I find the correct application identifier on macOS?

Open Terminal and run `osascript -e 'id of app "Application Name"'` (replacing "Application Name" with the target app). This outputs the bundle identifier (e.g., `com.apple.Safari`) required for the TOML table key.

### What happens if I edit config.toml while the GUI is running?

The GUI writes configurations atomically and maintains a file lock. If you edit [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) externally while the GUI is open, the GUI will reject subsequent saves to prevent data loss. Restart the GUI or the background agent to reload the modified configuration.