quickshell: hold tray menu height so switching morphs instead of regrowing

Switching to a tray menu whose items were not currently loaded
collapsed fullHeight at the instant of the switch, so the chrome
morphed DOWN to a stub and replayed the vertical grow when the items
landed, rather than moving across from the previous panel.

An empty Card is not height 0 but 2*cardPad, so loaded-ness has to come
from the model: menuLoaded tracks menuOpener.children. While a newly
assigned menu is loading, fullHeight holds the last loaded height, so
the morph stays continuous and the correction on arrival is small —
nil when it is the same menu as last time.

ui.nix radius knob at 20.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-07-28 15:05:05 +01:00
parent 196b71bf25
commit cca2d62763
2 changed files with 23 additions and 2 deletions

View file

@ -2108,7 +2108,28 @@ in
id: contextMenu id: contextMenu
property var trayItem: null property var trayItem: null
fullWidth: menuItems.width + 2 * Theme.panelGap fullWidth: menuItems.width + 2 * Theme.panelGap
fullHeight: menuItems.height + 2 * Theme.panelGap
// While a freshly assigned menu is still loading, the Card
// is empty and an empty Card is not height 0, it is
// 2*cardPad so the panel would morph DOWN to a stub and
// then regrow once the items land, instead of moving
// across. Hold the last loaded height until the new items
// arrive so the morph stays continuous. The correction is
// small, and nil when it is the same menu as last time.
readonly property bool menuLoaded:
menuOpener.children && menuOpener.children.values.length > 0
property real lastMenuHeight: 0
fullHeight: (menuLoaded ? menuItems.height
: Math.max(menuItems.height, lastMenuHeight))
+ 2 * Theme.panelGap
Connections {
target: menuItems
function onHeightChanged() {
if (contextMenu.menuLoaded)
contextMenu.lastMenuHeight = menuItems.height;
}
}
// Deliberately NOT cleared on close. Nulling the menu threw // Deliberately NOT cleared on close. Nulling the menu threw
// away the loaded items, and the only thing that refills // away the loaded items, and the only thing that refills

View file

@ -12,5 +12,5 @@
# Theme.radiusTiny = radius * 0.5 # Theme.radiusTiny = radius * 0.5
# hyprland decoration.rounding = radius # hyprland decoration.rounding = radius
{ {
radius = 24; radius = 20;
} }