Understanding the Actions Ring in OpenLogi: A Complete Guide to Eight-Slot Layouts
The Actions Ring is OpenLogi's host-side radial UI that displays eight fixed positions for instant action execution, with layouts defined by the ActionRingLayout type and customizable per application through TOML configuration or runtime APIs.
OpenLogi is an open-source automation platform for Logitech input devices that provides advanced gesture and button remapping. The Actions Ring serves as the primary circular overlay menu that appears when device-specific triggers invoke the ShowActionsRing command, allowing users to execute bound actions from eight directional slots.
What Is the Actions Ring in OpenLogi?
The Actions Ring functions as a context-aware radial menu that renders on the host machine when activated. When a user triggers ShowActionsRing—typically via a remapped mouse button or gesture—the overlay appears centered on the active device location. The agent then monitors directional input to determine which of the eight slots the user selects, executing the corresponding bound action immediately.
This UI component bridges hardware input with software automation, providing tactile visual feedback through the eight-slot architecture defined in the core binding system.
The Eight-Slot Layout Architecture
OpenLogi implements the ring layout through strict type definitions in crates/openlogi-core/src/binding/action_ring.rs. The eight-slot system uses fixed geometric positions to ensure muscle memory and predictable interaction patterns.
ActionRingSlot Enum Positions
The ActionRingSlot enum defines eight clockwise positions starting from the top, as implemented in lines 20-40 of the core binding file:
- Top — 12 o'clock position
- TopRight — Diagonal between top and right
- Right — 3 o'clock position
- BottomRight — Diagonal between right and bottom
- Bottom — 6 o'clock position
- BottomLeft — Diagonal between bottom and left
- Left — 9 o'clock position
- TopLeft — Diagonal between left and top
These variant names remain stable across the TOML configuration schema and Rust APIs, ensuring backward compatibility for user configurations.
Default Layout Configuration
When no custom configuration exists for a device, OpenLogi supplies a built-in default layout through ActionRingLayout::default (lines 64-73). The default mapping assigns common clipboard and editing actions to cardinal directions:
use openlogi_core::binding::{ActionRingLayout, ActionRingSlot, Action};
let default = ActionRingLayout::default();
assert_eq!(default.slots[&ActionRingSlot::Top].action(), &Action::Cut);
assert_eq!(default.slots[&ActionRingSlot::Right].action(), &Action::Paste);
The default implementation ensures immediate usability while allowing complete customization through the configuration system.
Configuring Actions Ring Layouts
OpenLogi provides multiple interfaces for modifying ring layouts: runtime GUI APIs for interactive editing and persistent TOML configuration for static definitions.
Runtime Editing via AppState
The desktop GUI frontend exposes layout manipulation through helper methods in crates/openlogi-desktop/src/state/action_ring.rs. These APIs enable dynamic modification without restarting the application:
current_action_ring_layout()— Retrieves the effective layout for the active device and foreground applicationcommit_action_ring_slot(slot, action)— Updates or clears a specific slot bindingcommit_action_ring_icon(slot, icon)— Assigns visual icons to slots for better recognitionset_editing_action_ring_app(app)— Switches to application-specific layout editing mode
These methods interact with the underlying ActionRingConfig structure while providing immediate visual feedback in the overlay renderer at crates/openlogi-overlay/src/ring.rs.
Persistence and Per-Application Overrides
The ActionRingConfig struct (lines 89-105) stores both default layouts and per-application overrides. When the foreground application matches a key in the per_app map, its layout supersedes the default through the effective_layout method (lines 28-33):
[devices."logitech-m570".action_ring]
enabled = true
haptics = true
[devices."logitech-m570".action_ring.default.slots]
Top = { action = "Copy", icon = "Keyboard" }
Right = { action = "Paste" }
[devices."logitech-m570".action_ring.per_app."com.apple.Safari".slots]
Top = { action = "NewTab" }
Empty slots are omitted from the TOML table, causing the ring to skip rendering those positions or display them as disabled depending on the skin configuration.
Practical Implementation Examples
Creating Custom Layouts in Rust
For plugin developers or advanced users, ActionRingLayout provides methods to programmatically construct configurations:
use openlogi_core::binding::{
ActionRingLayout, ActionRingSlot, ActionRingEntry, RingAction, Action,
};
let mut layout = ActionRingLayout::default();
// Replace the "Top" slot with a custom shortcut
let custom = RingAction::new(Action::CustomShortcut("Cmd+N".into()))
.expect("custom shortcut is a valid ring action");
layout.set_action(ActionRingSlot::Top, Some(custom));
// Add a custom icon to the "Right" slot
layout.set_icon(ActionRingSlot::Right, Some(openlogi_core::binding::ActionRingIcon::Keyboard));
Modifying Layouts via the GUI API
Application-specific overrides can be configured at runtime through the desktop state management:
// Assuming `app_state` is an `AppState` instance
app_state.set_editing_action_ring_app(Some("com.apple.Safari".to_string()));
app_state.commit_action_ring_slot(ActionRingSlot::Bottom, None); // clear Bottom slot
app_state.commit_action_ring_icon(
ActionRingSlot::Bottom,
Some(openlogi_core::binding::ActionRingIcon::Mouse),
);
This approach enables context-sensitive automation where the Actions Ring presents different options in Safari versus Xcode, without requiring configuration file edits.
Summary
- The Actions Ring provides an eight-slot radial overlay (
Top,TopRight,Right,BottomRight,Bottom,BottomLeft,Left,TopLeft) for executing bound actions in OpenLogi. - Layouts are defined by
ActionRingLayoutincrates/openlogi-core/src/binding/action_ring.rs, with defaults defined at lines 64-73. - Per-application overrides are supported through
ActionRingConfig(lines 89-105), resolved via theeffective_layoutmethod. - Runtime modifications use
AppStatemethods incrates/openlogi-desktop/src/state/action_ring.rs. - The overlay renderer at
crates/openlogi-overlay/src/ring.rshandles the visual presentation and input detection.
Frequently Asked Questions
How do I enable the Actions Ring for my Logitech device?
Configure the action_ring.enabled key to true in your device's TOML configuration section. You must also map a physical button or gesture to the ShowActionsRing action through the standard binding system. When triggered, the ring overlay renders at the cursor position displaying the eight configured slots.
Can I have different Actions Ring layouts for different applications?
Yes, OpenLogi supports per-application layouts through the per_app map in ActionRingConfig. Set the application bundle identifier (macOS) or process name as the key, then define slot overrides specific to that context. The effective_layout method automatically selects the appropriate configuration based on the currently focused window.
What happens if I leave an Actions Ring slot empty?
Empty slots—represented by None in Rust or omitted entries in TOML—render as disabled positions in the overlay. The ring still maintains the eight-slot geometric structure for consistency, but empty slots do not respond to selection input and typically display with reduced opacity or specific disabled styling depending on the active theme.
Which source files control the Actions Ring behavior?
The core data structures reside in crates/openlogi-core/src/binding/action_ring.rs (lines 1-105+), containing ActionRingSlot, ActionRingLayout, and ActionRingConfig. The desktop GUI integration lives in crates/openlogi-desktop/src/state/action_ring.rs, while the visual overlay implementation is located in crates/openlogi-overlay/src/ring.rs.
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 →