AprilNEA / AprilNEA/OpenLogi

[Feature]: Render real application icons for OpenApplication slots in the Actions Ring

Open
#875 1 comment 0 reactions 0 assignees View on GitHub
area: gui platform: all type: feature
Dominant language
Rust
Stars
21k
Forks
675
Avg merge
2d 5h
Merged PRs (30d)
172

Description

### Pre-flight checklist

- [x] I searched existing issues and the Roadmap, and this isn't already tracked. (Closest matches are #775 and #630, both unrelated to icon rendering.)

### Problem / motivation

I use the Actions Ring mostly as an app launcher — several slots bound to `OpenApplication`. Every one of them renders the same generic `Applications` glyph, because that's the hardcoded default in `ActionRingIcon`:

```rust
Action::OpenApplication(_) => Self::Applications,
```

So a ring with three or four app launchers is visually undifferentiated at exactly the moment you need to pick one. Labels don't close the gap: only the *hovered* slot renders its label in the ring centre, so you can't scan the ring and see which slot is which — you have to hover each one in turn, which defeats the point of a radial menu.

The workaround is to hand-assign an unrelated glyph per app (I currently have `Star` = Claude, `Book` = Obsidian, `Globe` = Arc, `Terminal` = VS Code). That's arbitrary, has to be memorised, doesn't scale past a handful of apps, and for some apps there's simply no reasonable glyph in the set — nothing in the 53 `ActionRingIcon` variants means "code editor".

### Proposed solution

For slots whose action is `OpenApplication`, render the target application's real icon instead of a glyph — ideally as the default when `icon` is omitted, keeping an explicit `icon = "..."` as an override so current configs keep working.

Platform sources for the icon:

- **macOS** — `NSWorkspace.shared.icon(forFile:)` on the bundle path
- **Linux** — `Icon=` from the desktop entry, resolved through the icon theme
- **Windows** — extract the executable's embedded icon

The blocker is that icon resolution is currently compile-time: `ActionRingIcon::asset_path` is a `const fn` returning a `&'static str`, and the overlay renders it as `svg().path(icon_path)`. Supporting app icons means the overlay needs a second, runtime-resolved image path (or raster handle) alongside the static SVG case — so `ActionRingEntry`'s presentation would need to carry "static glyph" vs "resolved app icon" rather than always an `ActionRingIcon`.

If loading real icons is unwanted (extra platform FFI, caching, theming/tinting concerns in the overlay's monochrome style), a much cheaper partial fix would be rendering the first letter or two of the slot's `display_name`/`label` as a text glyph for `OpenApplication` slots. Less pretty, but it makes app slots distinguishable at a glance with no image pipeline.

### Alternatives considered

- **Distinct hand-picked glyphs per app** — what I do today. Works for 3–4 apps, arbitrary and unmemorable beyond that, and some apps have no sensible glyph.
- **Relying on labels** — insufficient, since labels only render for the hovered slot.
- **Adding a custom icon path to the config** (e.g. `icon_path = "/path/to/foo.png"`) — more flexible but more config surface; auto-resolving from the app bundle covers the common case with zero user effort.

### Related area(s)

- [x] GUI
- [x] Button actions / remapping
- [x] Configuration (TOML)

### Additional context

Relevant code (as of `master` today):

- `crates/openlogi-core/src/binding/action_ring/icon.rs` — `ActionRingIcon`, `asset_path`, and the `OpenApplication` → `Applications` default
- `crates/openlogi-overlay/src/ring.rs` — `slot_element`, which renders `svg().path(icon_path)` and the hover-only centre label

Environment: macOS, OpenLogi 0.7.7, MX Master 4 over Bluetooth.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with crates/openlogi-core/src/binding/action_ring/icon.rs to trace ActionRingIcon, asset_path, and the OpenApplication default, then read crates/openlogi-overlay/src/ring.rs at slot_element. The work needs a defined presentation path for static glyphs versus resolved application icons, covering the listed platform sources and preserving explicit icon overrides; the text also offers initials as a smaller fallback.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.