From e45c9644a1f009e995ed2d6877a2d5fa91948474 Mon Sep 17 00:00:00 2001 From: rope Date: Sun, 30 Aug 2026 13:56:28 +0100 Subject: [PATCH] quickshell: merge menu and toast into one surface, drop the double ease The bump was two animations stacked: _dropdownRect is positioned off chrome.y, so chrome already eased the panel to wherever y resolved, and the Behavior added last commit put an OutExpo behind an OutExpo. Panels now land ON the toast rather than a panelGap short of it, buried half a radius so the shader smins them into one outline with a shared waist. Cards inside still clear each other by ~14px. --- settings/quickshell.nix | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/settings/quickshell.nix b/settings/quickshell.nix index 6bcc18f..0fe5c9d 100644 --- a/settings/quickshell.nix +++ b/settings/quickshell.nix @@ -4988,10 +4988,18 @@ in // to sit in ends short of it. Only the band the toast is // actually on shrinks; the other one is still the frame. readonly property bool toastBlocks: toastItem.visible && toastItem.isPrimary + readonly property real toastMerge: Theme.radius / 2 readonly property real lo: toastBlocks && !toastItem.atBottom - ? Math.max(yMin, toastItem.y + toastItem.height + Theme.panelGap) : yMin + ? Math.max(yMin, toastItem.y + toastItem.height - 16 - toastMerge) : yMin + // Panel surface spans [y + 8, y + height - 8]; the toast's + // starts at its y + 8. Landing the first ON the second (plus + // a half-radius of burial, the fillet scale the shader smins + // at) merges them into one outline with a shared waist, + // rather than parking two surfaces a hairline apart. The + // cards inside still clear each other by ~14px: 12 of panel + // padding, 8 of toast inset, less the burial. readonly property real hi: toastBlocks && toastItem.atBottom - ? Math.min(yMax, toastItem.y - Theme.panelGap - height) : yMax + ? Math.min(yMax, toastItem.y + 16 + toastMerge - height) : yMax // Where the panel lands when it just tracks its widget. // hi < lo means the panel is taller than what the toast // leaves — nothing to be done, so it takes the frame and @@ -5005,22 +5013,19 @@ in // stops — no flag to remember to flip. A panel taller than // the screen has yMax < yMin, so yTracked pins to yMin and // the first branch catches it. - // Snapping still tests against the FRAME, not against a - // toast-shortened edge: a panel stopping above a toast is - // meant to read as floating clear of it, not fused to it. + // Snapping still tests against the FRAME. A panel held off + // a band by a toast is already fused to the toast, which is + // itself fused to that band — one outline either way. y: Math.round( yTracked - yMin <= Theme.snapDist ? yMin : yMax - yTracked <= Theme.snapDist ? Math.max(yMin, yMax) : yTracked) - // A toast arriving under an open menu moves it. Match the - // chrome's morph, or the content jumps while the surface - // it sits in slides. Off while closed so opening still - // places the panel instantly. - Behavior on y { - enabled: dropdown.open - NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo } - } + // No Behavior here on purpose: _dropdownRect is positioned + // off chrome.y, and chrome already eases to whatever this + // resolves to. Animating y as well put an OutExpo behind an + // OutExpo, which is what made a toast arriving under an + // open menu look like it physically shoved it. width: fullWidth + 4 // +24, not +16: the shader insets the panel 8px top and // bottom, so +16 left the panel edge flush with the content