Skip to content

Show hotkey chips on menu rows a keybinding also reaches - #8569

Open
pranavbabu wants to merge 3 commits into
omacom:quattrofrom
pranavbabu:menu-hotkey-chips
Open

pranavbabu wants to merge 3 commits into
omacom:quattrofrom
pranavbabu:menu-hotkey-chips

Conversation

@pranavbabu

@pranavbabu pranavbabu commented Aug 27, 2026 •

Copy link
Copy Markdown

Rows in the menu that a keybinding also triggers now carry that chord as a small muted chip on their right edge — Learn > Keybindings reads SUP+K, the System submenu SUP+ESC, the default terminal's row in Apps SUP+RET. The chip teaches the faster path to whatever the user just navigated to by hand.

image image

Oleh Kupriianov and others added 2 commits August 27, 2026 09:39
Rows in the Omarchy menu that a keybinding also triggers now carry that
chord as a small muted chip on their right edge — Learn > Keybindings
reads SUPER + K, the System submenu SUPER + ESCAPE, and the default
terminal's row in Apps SUPER + RETURN — teaching the faster path to what
the user just navigated to.

The chords are derived from the live binds rather than declared twice:
omarchy-menu-hotkeys reads the keybindings menu's cached records
(omarchy-menu-keybindings --records) and reports one cmd/app row per
exec chord. MenuModel.hotkeyIndex matches them onto rows by action
(normalizing quoting, Exec field codes, and launcher prefixes, with
webapp launches reduced to their URL), by menu routes the bind opens,
and onto app rows by resolved desktop id or the entry's Exec. A rebind
in the hypr config moves the chip with it; an explicit hotkey: field in
JSONC overrides for rows whose action spells the same launch
differently.

The shell runs the batch like the guards — per (re)load and per open,
never blocking the open path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On a 300px menu card a spelled-out chord is wider than the title beside
it: "SUPER SHIFT CTRL + SPACE" runs 24 characters, and the brightness
binds reach 29, so contentColumn collapsed and the row's label elided —
Apps, whose titles are the longest, worst of all.

MenuModel.compactChord renders the chip's own spelling: modifiers to
three letters, long X11 key names to what the key does, joined by a bare
"+". SHIFT + XF86MonBrightnessDown becomes SFT+BRIDN, 29 characters down
to 9; the widest chord left is 15. It applies to explicit hotkey: fields
too, so a JSONC override reads like a derived chip. The keybindings menu
keeps the spelled-out form — it has the width for it.

The chip also caps at a third of the row and elides, so a chord no
abbreviation can save truncates before the title it belongs to does.

That spelling wants a size under the old floor of caption, so
Style.font.micro (0.75, 9px) joins the type scale, overridable from a
theme's [font] block like every other token.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings August 27, 2026 11:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds derived hotkey chips to menu rows, helping users discover keyboard shortcuts.

Changes:

  • Derives and matches live keybindings to menu actions, routes, and apps.
  • Renders compact hotkey chips with a new micro font token.
  • Adds shell tests and documentation.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
bin/omarchy-menu-hotkeys Reports command and app hotkeys.
bin/omarchy-menu-keybindings Exposes cached binding records.
shell/plugins/menu/MenuModel.js Matches and compacts hotkeys.
shell/plugins/menu/Menu.qml Refreshes and renders hotkey chips.
shell/Commons/Style.qml Adds the micro font token.
default/omarchy/omarchy-menu.jsonc Documents the hotkey field.
config/omarchy/extensions/omarchy-menu.jsonc Documents extension overrides.
default/themed/shell.toml.tpl Adds the micro-size override.
docs/menu.md Documents hotkey derivation and display.
docs/omarchy-shell.md Documents the font token.
test/shell.d/menu-hotkeys-test.sh Tests reporting, matching, and compaction.
test/shell.d/menu-test.sh Updates menu-row expectations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread shell/plugins/menu/MenuModel.js Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@shmichael

Copy link
Copy Markdown

I'd find this useful for learning shortcuts while browsing the menu. A few suggestions:

  • Selected-item-only option: Could a config option show the shortcut only for the currently selected/hovered row? That would reduce visual clutter while still teaching the shortcut at the point of use.
  • Prefer fewer modifiers: When several active shortcuts reach the same action, prefer the one with the fewest modifiers, then the shortest displayed chord, with a stable tie-break. This would be more useful than taking whichever binding happens to come first.
  • Optional Mac-style symbols: A text/symbols setting could use ⌘ for Super, ⌃ for Ctrl, ⌥ for Alt, and ⇧ for Shift. For example, ⌃⌘H. This would also help keep longer chords compact.
  • Hide hints when space is insufficient: On narrow menus or with larger fonts, hide the hint if the full shortcut cannot fit alongside a useful amount of the item label. Basing this on available row width and measured text would handle scaling better than a screen-resolution cutoff. A truncated shortcut is difficult to learn from.

On performance, the asynchronous loading and in-memory index already look like a good foundation. For weaker machines, a few things seem worth considering:

  • Avoid rebuilding the index and display when a refresh returns unchanged data. Selection changes should remain a lookup/render operation, without processes or binding scans.
  • Since refresh currently runs on every open, consider invalidating on binding/config, keyboard-layout, and default-app changes where reliable notifications exist, with a bounded asynchronous refresh fallback for runtime changes. Coalesce refresh requests and keep menu opening independent of collection.
  • The underlying keybinding reader's configuration replay can hang on some Lua configs; Read keybindings from the running compositor instead of replaying configuration #11733 proposes collecting bindings inside the running compositor instead. It seems worth aligning with that work, or at least bounding collection time so repeated menu use cannot leave a collector consuming CPU indefinitely.
  • It would be useful to compare cold/warm menu-open latency and repeated navigation under CPU contention, including process counts and unchanged-refresh behaviour. Asynchronous work still costs CPU even when it does not delay the initial render.

These could be incremental refinements; the selected-item-only option is the one I'd value most.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants