Cap the menu height at the starting menu's height

The first submenu move or search keystroke already froze the card's top
edge; freeze the rows height at the same moment so drilling into a longer
menu scrolls behind the fold instead of growing the card.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-05 22:22:24 +02:00
co-authored by Claude Fable 5
parent 5d13b53eb5
commit 81778eaa02
+12 -3
View File
@@ -152,6 +152,9 @@ Item {
function availableRowsHeight() {
var top = panel.cardTop >= 0 ? panel.cardTop : Style.gapsOut
var available = panel.height - top - Style.gapsOut - root.contentMargin * 2 - root.headerHeight - root.contentSpacing
// The starting menu sets the ceiling along with the offset: drilling into
// a longer submenu scrolls behind the fold instead of growing the card.
if (panel.maxRowsHeight >= 0) available = Math.min(available, panel.maxRowsHeight)
// A card that swallows the whole screen reads as a page, not a menu.
return Math.min(available, Math.round(panel.height * 0.6))
}
@@ -1010,14 +1013,20 @@ Item {
// The card opens centered exactly as always. The first search keystroke
// or submenu move freezes the top line where it currently sits — from
// then on the card grows and shrinks downward instead of re-centering
// on every resize, which made the menu jump around. Closing unfreezes.
// on every resize, which made the menu jump around. The rows height is
// frozen at the same moment, so the starting menu also caps how tall the
// card may grow from there. Closing unfreezes both.
property int cardTop: -1
property int maxRowsHeight: -1
readonly property int centeredTop: Math.max(Style.gapsOut, Math.round((height - root.cardHeight) / 2))
readonly property int effectiveCardTop: cardTop >= 0 ? cardTop : centeredTop
function freezeCardTop() {
if (visible && cardTop < 0) cardTop = effectiveCardTop
if (visible && cardTop < 0) {
cardTop = effectiveCardTop
maxRowsHeight = root.visibleRowsHeight
}
}
onVisibleChanged: if (!visible) cardTop = -1
onVisibleChanged: if (!visible) { cardTop = -1; maxRowsHeight = -1 }
Rectangle {
anchors.fill: parent