How to Add Custom Actions and Icons to the OpenLogi Actions Ring

Define custom actions in your TOML profile's action_ring table, place SVG or PNG icons in the assets/action_ring/ directory, and the desktop client automatically forwards the configuration to the overlay via IPC using the ActionRingPresentation struct.

The Actions Ring in the AprilNEA/OpenLogi repository provides a radial quick-access interface for executing contextual commands. You can extend its default capabilities by adding custom actions and icons to the OpenLogi Actions Ring through declarative configuration and asset management, without modifying the core overlay source code.

Understanding the Actions Ring Architecture

The Actions Ring is rendered by the openlogi-overlay process and receives its data over the IPC channel defined in openlogi-ipc. Each slot in the ring is described by the ActionRingPresentation struct located in crates/openlogi-core/src/binding/action_ring.rs.

This struct contains two critical fields for customization:

  • icon: ActionRingIcon – Selects a built-in glyph or denotes a custom asset
  • literal: Option<String> – Available starting with protocol version v15, this field supplies the custom filename or label for user-defined icons

The desktop client (openlogi-desktop) watches your configuration files and translates TOML definitions into ActionRingInvocation messages that it sends to the overlay via tarpc-based IPC.

Configuring Custom Actions via TOML

Editing the Profile Configuration

Each OpenLogi profile can contain an action_ring table that maps directional slots to specific actions. Create or edit your configuration file at ~/.config/openlogi/config.toml (or the platform-equivalent path) to define custom behavior.

[profile.my_app.action_ring]
top = { action = "LaunchTerminal", icon = "my_terminal_icon" }
right = { action = "ToggleMute", icon = "my_mic_icon" }
bottom = { action = "ShowClipboard", icon = "custom_clipboard" }
left = { action = "LockScreen", icon = "my_lock" }

The action key specifies the command identifier, while the icon key references the asset filename (without extension) that the overlay should render for that slot.

Installing Custom Icon Assets

Supported Formats and Location

Custom icons are loaded by the ActionIcons asset source defined in crates/openlogi-ui/src/action_icons.rs. The system supports SVG and PNG formats for crisp scaling at different ring sizes.

Place your icon files in the assets/action_ring/ directory relative to the OpenLogi installation or configuration root. The asset source automatically discovers any files placed in this location during the overlay startup or refresh cycle.

Naming Conventions

The filename must exactly match the value specified in the TOML icon field. For example, if your configuration specifies icon = "my_terminal_icon", the file system should contain:


assets/action_ring/
├── my_terminal_icon.svg
├── my_mic_icon.svg
└── custom_clipboard.png

The ActionIcons loader in crates/openlogi-ui/src/action_icons.rs strips the extension when indexing, allowing you to reference the base name consistently across different supported formats.

Advanced Customization via Rust

Constructing ActionRingPresentation Programmatically

When building custom integrations or plugins, you construct the ActionRingPresentation struct directly to pass custom literals and labels. This approach is used internally by crates/openlogi-desktop/src/state/action_ring.rs when mapping user configuration to IPC messages.

use openlogi_core::binding::{
    ActionRingPresentation, 
    ActionRingSlot, 
    ActionRingIcon
};
use std::collections::BTreeMap;

let mut slots = BTreeMap::new();
slots.insert(
    ActionRingSlot::Top,
    ActionRingPresentation {
        icon: ActionRingIcon::Custom,               // Signals custom asset usage
        literal: Some("my_terminal_icon".into()),     // Matches filename in assets/
        label: Some("Terminal".into()),              // Displayed in UI editors
    },
);

Loading Icons with the ActionIcons Source

To verify asset availability programmatically, interact with the ActionIcons struct from openlogi-ui:

use openlogi_ui::action_icons::ActionIcons;

let icons = ActionIcons;
let my_icon = icons.load("my_terminal_icon.svg")?;
assert_eq!(my_icon.asset_path(), "my_terminal_icon.svg");

Sending Invocations via IPC

The desktop client emits the ring configuration to the overlay using the ActionRingInvocation RPC. You can trigger this manually when building custom automation:

use openlogi_ipc::{AgentClient, ActionRingInvocation};

// Assume `client` is an established tarpc client to the overlay
let invocation = ActionRingInvocation {
    slots, // BTreeMap<ActionRingSlot, ActionRingPresentation>
    // Additional fields: position, radius, etc.
};

client.invoke_action_ring(invocation).await?;

Modifying the Ring Layout

If you require non-standard slot positioning or a custom radius, edit the ActionRingLayout in crates/openlogi-core/src/binding/action_ring.rs. The layout defines the angular arrangement of slots (Top, Right, Bottom, Left) and their visual spacing.

Changes to the layout structure require restarting the overlay process, as the layout is read once at startup in crates/openlogi-overlay/src/ring.rs. However, content changes (new icons or actions) propagate immediately via the file-watching mechanism in crates/openlogi-desktop/src/features/action_ring/editor.rs.

Summary

  • Configure actions in the TOML action_ring table to map directional slots to command identifiers and icon names.
  • Place custom icons (SVG or PNG) in assets/action_ring/; the ActionIcons source in crates/openlogi-ui/src/action_icons.rs discovers them automatically.
  • Use the ActionRingPresentation struct to pass custom metadata, including the literal field for user-defined icon filenames (protocol v15+).
  • Leverage IPC via ActionRingInvocation to dynamically update the ring without restarting the entire OpenLogi stack.

Frequently Asked Questions

What image formats are supported for custom ring icons?

OpenLogi supports SVG and PNG files for custom icons placed in the assets/action_ring/ directory. The ActionIcons asset source in crates/openlogi-ui/src/action_icons.rs indexes these formats automatically and scales them appropriately for the ring's radial layout.

Do I need to restart OpenLogi after adding new custom actions?

No. The desktop client (openlogi-desktop) implements file watching on the configuration directory. When you save changes to config.toml or add new files to assets/action_ring/, the client automatically rebuilds the ActionRingInvocation and pushes it to the overlay via IPC, refreshing the ring on the next invocation.

Can I add more than four slots to the Actions Ring?

The default implementation in crates/openlogi-core/src/binding/action_ring.rs defines slots as an enum variant (Top, Right, Bottom, Left). To add additional positions such as diagonal slots, you must modify the ActionRingSlot enum and update the rendering logic in crates/openlogi-overlay/src/ring.rs to handle the new angular positions.

Why doesn't my custom icon appear in the ring?

Verify three specific items: first, confirm the filename matches the icon value in your TOML configuration exactly (case-sensitive); second, ensure the file resides in the correct assets/action_ring/ directory that the ActionIcons source monitors; third, check that you are running protocol version v15 or later if using the literal field for custom asset references, as defined in crates/openlogi-core/src/binding/action_ring/icon.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:

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 →