From 81778eaa026f0c9ed518a976f8aaf391d16bf63e Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 5 Aug 2026 20:04:21 +0200 Subject: [PATCH] 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 --- shell/plugins/menu/Menu.qml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/shell/plugins/menu/Menu.qml b/shell/plugins/menu/Menu.qml index e7b7e4d5..240196a3 100644 --- a/shell/plugins/menu/Menu.qml +++ b/shell/plugins/menu/Menu.qml @@ -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