diff --git a/shell/plugins/menu/MenuModel.js b/shell/plugins/menu/MenuModel.js index 3de9b8ee..556c1d77 100644 --- a/shell/plugins/menu/MenuModel.js +++ b/shell/plugins/menu/MenuModel.js @@ -309,11 +309,8 @@ function searchScore(items, entry, query) { else if (descriptionTextMatches(needle, descriptionText)) score = 60 if (entry.kind === "menu" || entry.kind === "link") score -= 2 - // mergeAppRows appends app rows after every menu item, so an app always - // loses the order tiebreak below to a menu entry that matches just as well. - // Searching an installed app's name should launch it, not offer to install - // or remove it. The bias stays under the 10-point gap between match tiers, - // so a menu entry that matches better still sorts first. + // App rows sort after all menu items, so they lose the tiebreak below to an + // equal match. Outrank those, but stay inside the tier so better ones win. if (entry.kind === "app") score -= 5 return score * 1000 + depthFor(items, entry.id) * 25 + entry.order diff --git a/test/shell.d/menu-test.sh b/test/shell.d/menu-test.sh index 8f838702..1035f9b6 100644 --- a/test/shell.d/menu-test.sh +++ b/test/shell.d/menu-test.sh @@ -110,9 +110,8 @@ assertDeepEqual( const defaultItems = menu.parseMenuJsonc(defaultMenuJsonc) const defaultById = Object.fromEntries(defaultItems.map(item => [item.id, item])) -// App rows land after every static item, so ranking has to survive the real -// menu's item count: with hundreds of entries ahead of them, the order -// tiebreak alone buries an installed app under Install and Remove. +// Needs the real menu: app rows sort after all menu items, and only at that +// item count does the order tiebreak alone bury an installed app. const rankBase = menu.mergeMenuSources(defaultItems, []) const ranked = menu.mergeAppRows(rankBase.items, rankBase.itemOrder, [ { id: 'apps.brave', parent: 'apps', kind: 'app', label: 'Brave', description: '', aliases: [] },