From 89615a526dc2a50749783027fb37e0e604f0df4c Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 29 Jun 2026 13:59:42 -0500 Subject: [PATCH] Render Omarchy menu icon with Omarchy font --- default/omarchy/omarchy-menu.jsonc | 3 ++- shell/plugins/menu/Menu.qml | 4 +++- shell/plugins/menu/MenuModel.js | 4 +++- test/shell.d/menu-test.sh | 14 ++++++++++---- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/default/omarchy/omarchy-menu.jsonc b/default/omarchy/omarchy-menu.jsonc index 47722300..36804fac 100644 --- a/default/omarchy/omarchy-menu.jsonc +++ b/default/omarchy/omarchy-menu.jsonc @@ -8,6 +8,7 @@ // calls provider_name() or a command named "name" to return JSON rows. // Optional fields: // aliases alternate `omarchy menu summon ` routes; also searchable + // iconFont font family used for the icon glyph, when it differs from the menu font // keywords extra search terms beyond id/label/aliases // when shell condition; hide row when it fails // checked shell condition; append ✓ when it succeeds @@ -283,7 +284,7 @@ "remove.development.elixir.phoenix": {"icon":"","label":"Phoenix","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env phoenix'"}, // Update - "update.omarchy": {"icon":"","label":"Omarchy","keywords":"system","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update"}, + "update.omarchy": {"icon":"","iconFont":"omarchy","label":"Omarchy","keywords":"system","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update"}, "update.channel": {"icon":"󰔫","label":"Channel","keywords":"stable rc dev edge source"}, "update.config": {"icon":"","label":"Config","keywords":"refresh default"}, "update.themes": {"icon":"󰸌","label":"Extra Themes","action":"omarchy-launch-floating-terminal-with-presentation omarchy-theme-update"}, diff --git a/shell/plugins/menu/Menu.qml b/shell/plugins/menu/Menu.qml index 8562b784..70c51817 100644 --- a/shell/plugins/menu/Menu.qml +++ b/shell/plugins/menu/Menu.qml @@ -410,6 +410,7 @@ Item { itemId: "dmenu." + i, kind: "dmenu", icon: "", + iconFont: "", label: label, target: "", detail: "", @@ -932,6 +933,7 @@ Item { required property string itemId required property string kind required property string icon + required property string iconFont required property string label required property string target required property string detail @@ -964,7 +966,7 @@ Item { visible: row.hasIcon text: row.icon color: row.hasCursor ? root.selectedText : root.foreground - font.family: root.fontFamily + font.family: row.iconFont.length > 0 ? row.iconFont : root.fontFamily font.pixelSize: Style.font.iconLarge width: Style.space(36) horizontalAlignment: Text.AlignHCenter diff --git a/shell/plugins/menu/MenuModel.js b/shell/plugins/menu/MenuModel.js index 2d8cb0bc..f3805108 100644 --- a/shell/plugins/menu/MenuModel.js +++ b/shell/plugins/menu/MenuModel.js @@ -38,6 +38,7 @@ function normalizeItem(id, raw) { parent: parent, kind: kind, icon: value.icon || "", + iconFont: value.iconFont || "", label: value.label || id, target: value.target || "", keywords: normalizeKeywords(id, aliases, value.keywords), @@ -95,7 +96,7 @@ function mergeMenuSources(defaultItems, userItems) { } if (!nextItems.root) { - nextItems.root = { id: "root", parent: "", kind: "menu", icon: "", label: "Go", target: "", keywords: "", description: "", aliases: [], when: "", checked: "", action: "", provider: "" } + nextItems.root = { id: "root", parent: "", kind: "menu", icon: "", iconFont: "", label: "Go", target: "", keywords: "", description: "", aliases: [], when: "", checked: "", action: "", provider: "" } nextOrder.unshift("root") } for (var k3 = 0; k3 < nextOrder.length; k3++) nextItems[nextOrder[k3]].order = k3 @@ -253,6 +254,7 @@ function displayRow(items, itemOrder, checkedResults, entry, detail, score, sect itemId: entry.id, kind: entry.kind, icon: entry.icon, + iconFont: entry.iconFont || "", label: labelFor(entry, checkedResults), target: target, detail: detail || "", diff --git a/test/shell.d/menu-test.sh b/test/shell.d/menu-test.sh index 731da5eb..ec7fad18 100644 --- a/test/shell.d/menu-test.sh +++ b/test/shell.d/menu-test.sh @@ -34,6 +34,7 @@ assertDeepEqual( parent: 'style', kind: 'action', icon: '', + iconFont: '', label: 'Themes', target: '', keywords: 'appearance colors', @@ -76,6 +77,7 @@ assertDeepEqual( itemId: 'style.theme', kind: 'action', icon: '', + iconFont: '', label: 'Theme picker', target: 'style.theme', detail: 'Style', @@ -92,12 +94,16 @@ assertDeepEqual( const defaultItems = menu.parseMenuJsonc(defaultMenuJsonc) const defaultById = Object.fromEntries(defaultItems.map(item => [item.id, item])) assert( - defaultById['update.omarchy'].icon === defaultById['learn.omarchy'].icon, - 'menu update Omarchy entry uses the menu-font Omarchy icon' + defaultById['update.omarchy'].icon === '\ue900', + 'menu update Omarchy entry uses the Omarchy glyph' ) assert( - !defaultMenuJsonc.includes('\ue900'), - 'menu entries do not use the private Omarchy bar-font glyph' + defaultById['update.omarchy'].iconFont === 'omarchy', + 'menu update Omarchy entry renders the private glyph with the Omarchy font' +) +assert( + /font\.family: row\.iconFont\.length > 0 \? row\.iconFont : root\.fontFamily/.test(menuQml), + 'menu rows support per-icon font families' ) assert(