Restore the selected menu row when going back - #7657
Conversation
setActiveMenu() always reset selectedIndex to 0, so goBack() (Left arrow / Backspace) landed on the first row of the parent menu instead of the item the user had drilled in from. navStack now remembers the selected index alongside each menu id, and goBack() restores it.
There was a problem hiding this comment.
Pull request overview
Restores parent-menu cursor position after returning from a submenu.
Changes:
- Stores menu IDs with selected indices in navigation history.
- Restores saved indices in
goBack(). - Adds regression assertions for navigation state.
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 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
shell/plugins/menu/Menu.qml |
Saves and restores cursor positions during navigation. |
test/shell.d/menu-test.sh |
Adds assertions for index preservation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A raw selectedIndex is only meaningful for the displayModel it was captured from. If the parent menu was filtered (search results) when a row was activated, going back cleared the filter before restoring the index, so it landed on an unrelated row in the unfiltered list. Key the remembered row by itemId instead, and remember the filter text alongside it so goBack() can restore the same search view (and reload volatile search providers) before looking the row up.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
shell/plugins/menu/Menu.qml:782
setActiveMenu()rebuilds and callssettleCursor()whileselectedIndexis still 0, then this block overwrites that settled result and unconditionally activates the remembered row. If that row became disabled while its submenu was open, the cursor is restored onto a non-selectable row, so the stated fallback for changed rows does not run. Set the remembered index first, then settle again so it remains selected when valid and advances to the nearest selectable row otherwise.
var restored = root.indexOfItemId(previous.selectedItemId)
if (restored >= 0) {
root.selectedIndex = restored
root.cursorActive = true
}
|
Reviewed on a disposable VM running this branch's shell. Nothing blocking — the fix does what it says, and I confirmed it in the running menu rather than only on paper. What ran. The worker's compositor was pointed at this branch ( Verified live. Descend from a non-first row and come back: the row is restored. Two levels down, back twice: both levels restored. Search Three things worth your attention, none of them blocking. 1. The new tests assert source text, not behaviour. Replacing 2. 3. The restore is identity-keyed only at the instant it happens. After that it is a bare index, and any later One thing to fix. The PR description still describes the first commit — Second opinion. Merge collisions. #7653 also edits Nothing pushed to your branch. This is waiting on a maintainer. |
goBack() was forcing the cursor onto the restored row unconditionally. If that row went disabled while its submenu was open, the cursor landed on it anyway instead of falling through to the nearest selectable row like settleCursor() does everywhere else. Also tighten the regression test: it previously only asserted that the lookup ran, not that its result drove the cursor.
|
Thanks for the thorough live review — pushed 0949894 to address the two actionable points:
Also updated the PR description to describe the actual final design ( On point 3 (drift after a later |
|
Re-reviewed at 0949894. It fixes the disabled-row problem, and I proved it rather than reading it: same worker setup as last time, shell running on this branch. The fix works, and here is the A/B. I built a throwaway menu extension with four rows under a I also checked the branch that does not go through your new call. When the remembered Two things I confirmed did not regress: descending from The test still asserts source text, and I want to be plain about what that buys you. Your new assertion does catch the exact sabotage you reproduced — swapping in The PR description now matches the code. Point 3 is agreed as pre-existing #7083 and out of scope. Second opinion. One thing for the maintainer, not for you. #7074 ("Remember cursor position when navigating back in the root menu", nickav, 16 Aug) is the same feature in the same two files. It stores a raw Tests. |
Summary
setActiveMenu()always resetselectedIndexto0, so pressing Left (or Backspace with an empty filter) to go back up a level in the Omarchy menu always landed on the first row instead of the item you'd drilled in from.navStacknow remembers{ id, filterText, selectedItemId }for the menu being left when descending.goBack()restores that filter (reloading volatile search providers if needed) sorebuildDisplay()regenerates the same view, then looks the remembered row up byitemIdvia a newindexOfItemId()and re-runssettleCursor()on it. The row is keyed by id rather than a raw index because the parent may have been filtered (search results) when the row was activated, and a raw index would land on an unrelated row once that filter is restored or cleared. Re-settling rather than forcing the cursor onto the found index means a row that went disabled while its submenu was open still resolves to the nearest selectable row instead of parking the cursor somewhere Enter won't run.Test plan
./test/shell.d/menu-test.shpasses, including regression assertions covering the remembered row/filter, the identity-based lookup, and that the restored index is actually applied throughsettleCursor()(not just looked up)./test/all— no new failures (pre-existing failures on this machine are environment-only: missingomarchy-pkgscheckout, file permissions, and flaky screen-capture/smoke tests unrelated to this change)