quickshell: close the tray-to-tray morph gap

Gating the held height on the model alone was not enough. The model
populating and the layout catching up are different frames: the
Repeater still has to build delegates and the Column re-measure, so
menuLoaded went true while the Card was still empty-sized and the panel
collapsed for a frame before regrowing.

Only tray-to-tray showed it, because that is the one path that
reassigns the menu handle — coming from a non-tray widget leaves the
handle unchanged, so nothing reloads.

menuReady now also requires the height to have grown past an empty Card
(2*cardPad = 16; the smallest real row is 28, so it cannot misfire).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-07-28 15:10:55 +01:00
parent cca2d62763
commit 31c584e7d1

View file

@ -2118,15 +2118,26 @@ in
// small, and nil when it is the same menu as last time. // small, and nil when it is the same menu as last time.
readonly property bool menuLoaded: readonly property bool menuLoaded:
menuOpener.children && menuOpener.children.values.length > 0 menuOpener.children && menuOpener.children.values.length > 0
// The model populating is NOT the same instant as the
// layout catching up: the Repeater still has to build its
// delegates and the Column re-measure. Gating on the model
// alone left a frame where menuLoaded was true but the Card
// was still empty-sized, so the panel collapsed and then
// regrew visible when switching between two tray icons,
// which is the only path that reassigns the handle.
// Require the height to have actually grown past an empty
// Card (which measures 2*cardPad, not 0).
readonly property bool menuReady:
menuLoaded && menuItems.height > 2 * Theme.cardPad
property real lastMenuHeight: 0 property real lastMenuHeight: 0
fullHeight: (menuLoaded ? menuItems.height fullHeight: (menuReady ? menuItems.height
: Math.max(menuItems.height, lastMenuHeight)) : Math.max(menuItems.height, lastMenuHeight))
+ 2 * Theme.panelGap + 2 * Theme.panelGap
Connections { Connections {
target: menuItems target: menuItems
function onHeightChanged() { function onHeightChanged() {
if (contextMenu.menuLoaded) if (contextMenu.menuReady)
contextMenu.lastMenuHeight = menuItems.height; contextMenu.lastMenuHeight = menuItems.height;
} }
} }