quickshell: animated close for all dropdown dismissals

BarDropdown.animateClose() morphs height to 0 then hides after
230ms. Used by auto-close timer, icon toggle, and switching
between dropdowns — old slides up while new slides down.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
rope 2026-05-26 17:20:48 +01:00
parent a8a129a9cd
commit dca7d49a5f

View file

@ -461,16 +461,18 @@ in
property var activeDropdown: null property var activeDropdown: null
function closeAllDropdowns() { function closeAllDropdowns() {
if (activeDropdown && activeDropdown.visible) { if (activeDropdown && activeDropdown.visible) {
activeDropdown.visible = false; activeDropdown.animateClose();
} }
activeDropdown = null; activeDropdown = null;
} }
function toggleDropdown(dd, setupFn) { function toggleDropdown(dd, setupFn) {
if (dd.visible) { if (dd.visible && !dd.closing) {
dd.visible = false; dd.animateClose();
activeDropdown = null; activeDropdown = null;
} else { } else if (!dd.visible) {
closeAllDropdowns(); if (activeDropdown && activeDropdown !== dd && activeDropdown.visible) {
activeDropdown.animateClose();
}
if (setupFn) setupFn(); if (setupFn) setupFn();
dd.visible = true; dd.visible = true;
activeDropdown = dd; activeDropdown = dd;
@ -835,12 +837,21 @@ in
component BarDropdown: PopupWindow { component BarDropdown: PopupWindow {
id: dropdown id: dropdown
property bool open: false property bool open: false
property bool closing: false
property real dropdownX: 0 property real dropdownX: 0
property real fullWidth: 200 property real fullWidth: 200
property real fullHeight: 200 property real fullHeight: 200
property int autoCloseMs: 3000 property int autoCloseMs: 3000
default property alias content: dropdownContent.data default property alias content: dropdownContent.data
function animateClose() {
if (!visible || closing) return;
closing = true;
open = false;
_autoClose.stop();
_closeDelay.start();
}
anchor.window: bar anchor.window: bar
anchor.rect.x: dropdownX - (fullWidth + 16) / 2 anchor.rect.x: dropdownX - (fullWidth + 16) / 2
anchor.rect.y: bar.height anchor.rect.y: bar.height
@ -854,10 +865,12 @@ in
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible) {
closing = false;
open = true; open = true;
_autoClose.restart(); _autoClose.restart();
} else { } else {
open = false; open = false;
closing = false;
_autoClose.stop(); _autoClose.stop();
} }
} }
@ -865,7 +878,13 @@ in
Timer { Timer {
id: _autoClose id: _autoClose
interval: dropdown.autoCloseMs interval: dropdown.autoCloseMs
onTriggered: bar.closeAllDropdowns() onTriggered: dropdown.animateClose()
}
Timer {
id: _closeDelay
interval: 230
onTriggered: { dropdown.visible = false; dropdown.closing = false; }
} }
MouseArea { MouseArea {