How to Configure Per-Direction Gesture Bindings in OpenLogi: Complete TOML Guide
OpenLogi uses a plain TOML configuration file where gesture buttons map distinct actions to each swipe direction (up, down, left, right, and optional diagonals) through a gesture-direction hash map in the bindings table.
OpenLogi is an open-source input remapping tool for Logitech devices that reads all user settings from a TOML file shared between its GUI and background agent. For gesture-capable hardware, you can bind individual actions to specific swipe directions rather than treating the button as a simple on/off switch. This per-direction binding system gives precise control over multi-directional input gestures.
Understanding the Gesture-Direction Map Structure
The bindings table under each [[devices]] entry supports three configuration patterns. According to the Configuration documentation, the third pattern enables per-direction gesture bindings:
| Pattern | Syntax | Use Case |
|---|---|---|
| Single action | Button = "Action" |
Standard press-to-activate buttons |
| Short/long pair | Button = { short = "ActionA", long = "ActionB" } |
Dual-function buttons with timing differentiation |
| Gesture-direction map | Button = { up = "A", down = "B", left = "C", right = "D" } |
Per-direction gesture bindings with distinct actions per swipe |
When a gesture button is held, OpenLogi's agent monitors pointer movement or native gesture sensor data. Upon detecting a directional swipe, it looks up the corresponding key in your map and fires that action. Unspecified directions are silently ignored.
Required TOML Schema and Device Structure
OpenLogi requires schema version 7 in your configuration file, as noted in docs/CONFIGURATION.md#L39-L40. Each device entry uses the physical key format [devices."receiver:<id>:slot:<n>"] and contains device metadata plus the bindings table.
Complete Device Entry Template
[devices."receiver:123456:slot:1"]
custom_name = "MX Master 3"
enabled = true
dpi = 1200
thumbwheel_sensitivity = 14
# Per-direction gesture bindings
bindings = {
# Standard buttons
Button1 = "Copy",
Button2 = { short = "Back", long = "Forward" },
# Gesture button with per-direction actions
GestureButton = {
up = "VolumeUp",
down = "VolumeDown",
left = "PreviousTrack",
right = "NextTrack"
}
}
Supported Gesture Directions
OpenLogi recognizes eight directional inputs for gesture buttons. The four cardinal directions are required for full functionality; diagonal directions are optional but available.
| Direction Key | Swipe Direction |
|---|---|
up |
Vertical upward |
down |
Vertical downward |
left |
Horizontal left |
right |
Horizontal right |
up_left (optional) |
Diagonal up-left |
up_right (optional) |
Diagonal up-right |
down_left (optional) |
Diagonal down-left |
down_right (optional) |
Diagonal down-right |
Full Eight-Direction Configuration Example
[devices."receiver:00112233:slot:2"]
custom_name = "MX Master 2S"
dpi = 1000
thumbwheel_sensitivity = 14
bindings = {
# CID 0xD0 gesture button with all directions mapped
Thumbwheel = {
up = "ShowDesktop",
down = "MissionControl",
left = "PreviousSpace",
right = "NextSpace",
up_left = "BrightnessUp",
up_right = "BrightnessDown",
down_left = "MediaPlayPause",
down_right = "MediaStop"
},
# Regular buttons for comparison
Button3 = "PlayPause",
Button4 = { short = "Back", long = "Forward" }
}
Partial Direction Bindings
You are not required to define all directions. Omitting a direction key disables that gesture entirely—useful when you want to prevent accidental triggers in specific orientations.
bindings = {
GestureButton = {
up = "VolumeUp",
down = "VolumeDown"
# left and right omitted: horizontal swipes are ignored
}
}
How Per-Direction Gestures Are Processed Internally
The gesture pipeline spans multiple crates in the OpenLogi source tree:
-
Event Capture: [
crates/openlogi-hook/src/lib.rs](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-hook/src/lib.rs) captures raw HID++ gesture events from the device hardware, as documented in [crates/openlogi-hook/AGENTS.md](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-hook/AGENTS.md). -
Direction Accumulation:
crates/openlogi-device/src/session/gesture/contains the swipe accumulator that tracks pointer displacement while the gesture button remains held. -
Action Resolution: The accumulated direction string (e.g.,
"up_left") is matched against your TOML map keys. The corresponding action variant—defined in the coreActionenum—gets queued for execution. -
OS Injection: [
crates/openlogi-inject/src/inject.rs](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-inject/src/inject.rs) performs the final system-level input injection.
This architecture means your TOML edits directly control the action variant passed through the entire pipeline.
Configuration File References
| File | Purpose |
|---|---|
docs/CONFIGURATION.md |
Complete TOML schema documentation including bindings table structure |
docs/config.example.toml |
Validated working example with per-direction gesture configurations |
crates/openlogi-core/src/action.rs |
Action enum variants available for TOML strings |
Applying Your Configuration
After editing your config.toml:
- Save the file with valid TOML syntax (verify with
toml-testor similar if unsure) - Reload through the OpenLogi GUI, or restart the background agent
- Test gestures on your configured device; omitted directions should produce no response
Summary
- OpenLogi configures per-direction gesture bindings through TOML hash maps in the
bindingstable, not through a graphical binding interface - Use the pattern
GestureButton = { up = "Action", down = "Action", ... }to assign distinct actions to each swipe direction - Eight directions are supported: four cardinal and four diagonal; undefined directions are ignored during gesture recognition
- The configuration flows from raw HID++ capture through
crates/openlogi-hook, direction accumulation incrates/openlogi-device/src/session/gesture/, and final injection viacrates/openlogi-inject - Schema version 7 is mandatory; reference
docs/config.example.tomlfor syntax validation
Frequently Asked Questions
What happens if I define both a single action and a gesture-direction map for the same button?
You cannot combine patterns for a single button key. Each bindings entry must use exactly one of the three forms: single string, short/long table, or direction map. The TOML parser will reject overlapping definitions. Choose the pattern that matches your button's hardware capabilities—gesture buttons should use the direction map exclusively.
Can I use mouse movement instead of the native gesture sensor for direction detection?
OpenLogi supports both native HID++ gesture events and pointer-based accumulation. The crates/openlogi-device/src/session/gesture/ module handles the abstraction; your TOML configuration remains identical regardless of detection method. The engine automatically selects the appropriate source based on device capabilities reported during initialization.
Why are my diagonal gestures not registering?
Diagonal detection requires sufficient displacement in both axes during the swipe. If your thumbwheel_sensitivity or DPI setting is too low, small diagonal movements may be categorized as purely horizontal or vertical. Increase the sensitivity value in your device configuration, or exaggerate diagonal swipe angles during testing. Verify your TOML uses the correct underscore format: up_left, not upLeft or up-left.
Where can I find the complete list of valid action strings for my gesture map?
Valid action strings are defined as enum variants in [crates/openlogi-core/src/action.rs](https://github.com/AprilNEA/OpenLogi/blob/master/crates/openlogi-core/src/action.rs). The docs/config.example.toml file also contains extensively commented examples showing available actions. If you reference an undefined action string, the agent will log a configuration error at startup and skip that binding entry.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →