How to Configure Per-Direction Gesture Bindings in OpenLogi

OpenLogi maps the gesture button to five distinct actions—Up, Down, Left, Right (swipes), and Click (press without movement)—allowing per-direction configuration via TOML tables under bindings.GestureButton.

OpenLogi is an open-source input customization framework that treats the gesture button as a multi-directional input device. Configuring per-direction gesture bindings requires editing device-specific TOML configuration files to map each swipe direction to system actions. This article breaks down the configuration syntax and the internal Rust implementation that processes these bindings according to the OpenLogi source code.

TOML Configuration Syntax for Gesture Bindings

Per-direction gesture bindings are defined in a device's configuration section using a dedicated GestureButton table. Each direction represents a key mapping to an action string, as documented in docs/config.example.toml.

[devices."receiver:aabbccdd:slot:1".bindings.GestureButton]
Click = "MissionControl"
Up    = "MissionControl"
Down  = "AppExpose"
Left  = "PreviousDesktop"
Right = "NextDesktop"

The configuration supports standard TOML syntax for device-specific overrides. For example, to customize gestures for an MX Master mouse:

[devices."unit:6be9d300".bindings.GestureButton]
Up    = "MissionControl"
Down  = "ShowDesktop"
Left  = "PrevTab"
Right = "NextTab"
Click = "AppExpose"

Internal Architecture and Defaults

The system models the five gesture slots using the GestureDirection enum and provides automatic fallback values.

The GestureDirection Enum

The canonical representation of gesture directions is defined in crates/openlogi-core/src/binding/gesture.rs. The GestureDirection enum provides the ordering, labels, and translation keys for all five possible inputs: Up, Down, Left, Right, and Click.

Default Gesture Bindings

When a user omits a direction from their configuration, OpenLogi supplies sensible defaults via the default_gesture_binding function in crates/openlogi-core/src/binding/defaults.rs. The following table shows the fallback actions assigned when a gesture button is first promoted to a gesture binding:

Direction Default Action
Up Action::MissionControl
Down Action::ShowDesktop
Left Action::PrevTab
Right Action::NextTab
Click Action::AppExpose

The full default binding map is seeded via default_binding_for in the same file, ensuring that new gesture configurations inherit these values immediately.

Config Parsing and Merging

During configuration loading, the raw gesture map (raw.gesture_bindings) is restructured under ButtonId::GestureButton in crates/openlogi-core/src/config/device.rs. The parser handles backward compatibility by merging gesture maps with legacy button_bindings entries. Critically, the logic ensures that a legacy single GestureButton entry does not resolve to a Binding::Single, preserving the multi-directional nature of the input.

Runtime Projection

At runtime, the system extracts the active per-direction map through the oshook_gestures_for helper function in crates/openlogi-core/src/bindings.rs (lines 29-38). This function filters the binding collection to return only Binding::Gesture entries for a given device and application context. The resulting map translates raw XY swipe events from the hardware into the configured Action variants defined in the user's TOML file.

Summary

  • Five Directions: OpenLogi recognizes Up, Down, Left, Right swipes and a Click (non-swipe press) as distinct gesture inputs.
  • TOML Syntax: Configure bindings under [devices."id".bindings.GestureButton] with direction keys mapping to action strings.
  • Default Fallbacks: Unspecified directions automatically populate with values from default_gesture_binding in defaults.rs.
  • Internal Types: The GestureDirection enum in gesture.rs provides the canonical type system for these inputs.
  • Runtime Resolution: The oshook_gestures_for function extracts per-device, per-application gesture maps for event translation.

Frequently Asked Questions

What are the five configurable gesture directions in OpenLogi?

OpenLogi supports Up, Down, Left, Right (representing swipe movements), and Click (representing a press without directional movement). These are defined in the GestureDirection enum located in crates/openlogi-core/src/binding/gesture.rs.

Where are default gesture bindings defined in the OpenLogi source code?

Default bindings are defined in the default_gesture_binding function within crates/openlogi-core/src/binding/defaults.rs. This function returns Action::MissionControl for Up, Action::ShowDesktop for Down, Action::PrevTab for Left, Action::NextTab for Right, and Action::AppExpose for Click.

How does OpenLogi prevent legacy single-button entries from interfering with gesture configuration?

During config parsing in crates/openlogi-core/src/config/device.rs, the system explicitly merges raw gesture maps while ensuring that legacy single GestureButton entries do not resolve to Binding::Single. This preserves the multi-directional structure required for gesture processing.

Can gesture bindings be configured per-application in OpenLogi?

Yes. The oshook_gestures_for function in crates/openlogi-core/src/bindings.rs extracts gesture maps for specific device and application contexts, allowing the runtime to apply different per-direction gesture bindings depending on the active 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:

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 →