How to Configure Short and Long Press Bindings in OpenLogi

OpenLogi maps button presses under 500 ms to short actions and sustained holds of 500 ms or longer to long actions through TOML configuration entries parsed by the ButtonBinding struct in crates/openlogi-core/src/config.rs.

OpenLogi is an open-source runtime for Logitech HID++ devices that exposes button customization through a declarative TOML interface. When you configure short and long press bindings in OpenLogi, you create distinct execution paths for quick taps versus deliberate holds, allowing a single physical button to serve dual purposes based on timing thresholds enforced by the core library.

Understanding the 500‑Millisecond Threshold

OpenLogi’s runtime agent measures every button press duration to determine which action to dispatch:

  • Short press: Release occurs < 500 ms after the press event → executes the short binding.
  • Long press: Button remains held ≥ 500 ms → executes the long binding once the threshold is reached.

This timing logic is implemented in the runtime agent, which interfaces with the core library (openlogi-core) to resolve the appropriate ButtonBinding entry and validate the action name against the internal catalog defined in crates/openlogi-core/src/action.rs.

Configuration File Location and Structure

User-defined bindings reside in a TOML file that the Config struct deserializes at startup.

Default path: ~/.config/openlogi/config.toml

Reference example: The repository provides a canonical template at docs/config.example.toml that demonstrates valid syntax for combined short and long mappings.

The parser, located in crates/openlogi-core/src/config.rs, instantiates a ButtonBinding for each entry containing optional short and long string fields. Both fields accept identifiers that must exist in the action catalog (e.g., ShowDesktop, MissionControl, VolumeUp, PlayPause).

Defining Button Bindings in TOML

Each button entry uses inline table syntax to assign actions. You may define short, long, or both; omitting a field prevents that press type from triggering any action.


# ~/.config/openlogi/config.toml

Button1 = { short = "VolumeUp" }
Button2 = { long = "LaunchTerminal" }
Button3 = { short = "PreviousTrack", long = "PlayPause" }
DpiToggle = { short = "ShowDesktop", long = "MissionControl" }
  • Single-action bindings: Assign only short or long if you require only one behavior.
  • Dual-action bindings: Provide both keys to enable context-sensitive functionality (e.g., a brief click shows the desktop, while a hold opens Mission Control).

Complete Configuration Examples

The following snippet demonstrates the three common configuration patterns supported by the Config parser:


# ~/.config/openlogi/config.toml

# Example: Several buttons with short/long actions

# 1. Short-press only

SideButtonFront = { short = "Copy" }

# 2. Long-press only

SideButtonBack = { long = "Paste" }

# 3. Both actions on one button (500ms threshold determines which fires)

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

# 4. DPI toggle with distinct behaviors

DpiToggle = { short = "ShowDesktop", long = "MissionControl" }

After saving the file, you must restart the OpenLogi agent or trigger a config reload via the UI for the ButtonBinding changes to take effect.

Technical Implementation Details

When the runtime initializes, the Config struct in crates/openlogi-core/src/config.rs deserializes each TOML entry into a Rust struct resembling:

// Conceptual representation from crates/openlogi-core/src/config.rs
struct ButtonBinding {
    short: Option<String>,
    long: Option<String>,
}

The runtime agent monitors hardware events and calculates press duration. Upon crossing the 500 ms boundary, it queries the corresponding ButtonBinding field and dispatches the action string to the OS or OpenLogi’s internal command system. Invalid action names that do not appear in crates/openlogi-core/src/action.rs will fail validation during config loading.

Summary

  • OpenLogi uses a 500 ms threshold to differentiate short (< 500 ms) and long (≥ 500 ms) press behaviors.
  • Bindings are defined in ~/.config/openlogi/config.toml using the syntax ButtonName = { short = "Action", long = "Action" }.
  • The Config struct in crates/openlogi-core/src/config.rs parses the TOML into ButtonBinding instances with optional short and long fields.
  • Action names must match entries in the action catalog located in crates/openlogi-core/src/action.rs.
  • Changes require a restart or UI reload to activate.

Frequently Asked Questions

What is the exact timing threshold for long press detection?

The OpenLogi runtime treats any button held for 500 milliseconds or longer as a long press. Releases occurring before this threshold execute the short press action instead. This duration is hard-coded in the runtime agent logic and is not currently user-configurable via TOML.

Can I assign the same action to both short and long presses on one button?

Yes. The ButtonBinding struct accepts identical strings for both short and long fields, though this effectively disables the timing distinction. Alternatively, omitting one field leaves that press type unmapped, which is useful when you want to ignore accidental long presses or short taps.

Where can I find the list of valid action names for my configuration?

Valid identifiers are defined in the action catalog within crates/openlogi-core/src/action.rs. Common examples include ShowDesktop, MissionControl, VolumeUp, VolumeDown, PlayPause, PreviousTrack, and LaunchTerminal. Refer to this source file or the repository’s docs/CONFIGURATION.md for the complete, up-to-date list.

Do I need to restart OpenLogi after editing the config.toml file?

Yes. The Config struct loads and deserializes the TOML file once at startup. After modifying ~/.config/openlogi/config.toml, you must either restart the OpenLogi agent process or use the application’s UI reload function to re-parse the ButtonBinding definitions and apply new short or long press mappings.

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 →