diff --git a/settings/quickshell.nix b/settings/quickshell.nix index 6c09fb8..6bcc18f 100644 --- a/settings/quickshell.nix +++ b/settings/quickshell.nix @@ -2289,9 +2289,9 @@ in : Qt.vector4d(0, 0, 0, 0) // Toast melts into the band it sits against — toastItem // picks the side, this just buries the matching edge. - readonly property real toastTop: toastItem.atBottom || toastItem.floating + readonly property real toastTop: toastItem.atBottom ? toastItem.y + 8 : meltTop - readonly property real toastBot: toastItem.atBottom && !toastItem.floating + readonly property real toastBot: toastItem.atBottom ? meltBot : toastItem.y + 8 + _toastRect.height property vector4d toast: toastItem.visible && _toastRect.width > 0.5 ? Qt.vector4d(surfLeftX + _toastRect.width / 2, (toastTop + toastBot) / 2, @@ -4984,8 +4984,19 @@ in // is taller than the space (yMax < yMin). readonly property real yMin: Theme.frameWidth readonly property real yMax: bar.height - Theme.frameWidth - height + // A visible toast owns its band, so the space a panel has + // 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 lo: toastBlocks && !toastItem.atBottom + ? Math.max(yMin, toastItem.y + toastItem.height + Theme.panelGap) : yMin + readonly property real hi: toastBlocks && toastItem.atBottom + ? Math.min(yMax, toastItem.y - Theme.panelGap - height) : yMax // Where the panel lands when it just tracks its widget. - readonly property real yTracked: Math.max(yMin, Math.min(yMax, dropdownY - height / 2)) + // hi < lo means the panel is taller than what the toast + // leaves — nothing to be done, so it takes the frame and + // the toast rides over it for its five seconds. + readonly property real yTracked: Math.max(lo, Math.min(hi, dropdownY - height / 2)) x: Theme.barWidth // Snap to whichever band is within reach, and only then. // Proximity rather than an alignTop/alignBottom flag per @@ -4994,10 +5005,22 @@ 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. 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 } + } 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 @@ -7610,34 +7633,13 @@ in // Flush to that band (it melts into it), never centred on // the clock — a short toast floating mid-column reads as a // stray card instead of a surface growing out of the frame. - readonly property real baseY: atBottom + // The toast never moves for a menu: it is the thing the + // eye goes to, and a card that slides around the column + // depending on which dropdown happens to be open reads as + // a glitch. Dropdowns yield to it instead (see BarDropdown). + y: Math.round(atBottom ? bar.height - Theme.frameWidth - height - 8 - : Theme.frameWidth + 8 - // Dropdowns share this column, so a toast arriving under an - // open one lands on top of it. Step away from the band far - // enough to clear the panel, capped by the room left before - // the opposite frame — a full-height panel pushes the toast - // as far as it goes and no further, rather than off screen. - readonly property real dodge: { - const d = bar.activeDropdown; - if (!d || !d.visible) return 0; - const want = atBottom - ? (d.y + d.height + Theme.panelGap) - baseY - : (baseY + height + Theme.panelGap) - d.y; - const room = atBottom - ? baseY - Theme.frameWidth - 8 - : bar.height - Theme.frameWidth - 8 - height - baseY; - return Math.max(0, Math.min(want, room)); - } - // Once it has stepped away it is no longer against the - // band, so the shader draws it as a free-standing card. - readonly property bool floating: dodge > 0 - y: Math.round(atBottom ? baseY - dodge : baseY + dodge) - - // Opening a dropdown under a live toast moves it; slide. - Behavior on y { - NumberAnimation { duration: Theme.animContent; easing.type: Easing.OutCubic } - } + : Theme.frameWidth + 8) width: _toastRect.width + 4 height: _toastRect.height + 16