From db99982c798e2bee278b7ce80d1e575507236d41 Mon Sep 17 00:00:00 2001 From: rope Date: Thu, 11 Jun 2026 14:49:07 +0100 Subject: [PATCH] quickshell: soft-reload on config change so the tray host survives (fixes vesktop crash); suppress toast while popup open; animated hover states Co-Authored-By: Claude Fable 5 --- settings/quickshell.nix | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/settings/quickshell.nix b/settings/quickshell.nix index 17a71ff..953de55 100644 --- a/settings/quickshell.nix +++ b/settings/quickshell.nix @@ -31,8 +31,12 @@ in }; xdg.configFile = let + # Soft-reload quickshell in place: the process (and its DBus services — + # tray host, notification daemon) stays alive, so Electron apps with + # tray icons (vesktop) don't crash like they do on a hard restart. + # Falls back to a unit restart if the IPC socket isn't up. qsRestart = '' - ${pkgs.systemd}/bin/systemctl --user restart quickshell.service 2>/dev/null || true + ${pkgs.quickshell}/bin/qs ipc call shell reload 2>/dev/null || ${pkgs.systemd}/bin/systemctl --user restart quickshell.service 2>/dev/null || true ''; wifiConnectScript = pkgs.writeShellScript "wifi-connect" '' ssid="$1" @@ -131,6 +135,13 @@ in function powermenu(): void { launcher.toggleMode("power"); } } + // Soft reload, used by the nix onChange hook — keeps the + // process and its DBus services (tray host) alive. + IpcHandler { + target: "shell" + function reload(): void { Quickshell.reload(false); } + } + NotificationServer { id: _notifServer bodySupported: true @@ -328,6 +339,7 @@ in height: 32 radius: 6 color: list.currentIndex === index ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 100 } } Row { anchors.verticalCenter: parent.verticalCenter @@ -1143,7 +1155,7 @@ in } Behavior on height { - NumberAnimation { duration: 220; easing.type: Easing.OutCubic } + NumberAnimation { duration: 280; easing.type: Easing.OutExpo } } Item { @@ -1213,6 +1225,7 @@ in height: modelData.isSeparator ? 9 : 28 color: !modelData.isSeparator && itemMouse.containsMouse && modelData.enabled ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } radius: modelData.isSeparator ? 0 : 4 Rectangle { @@ -1336,6 +1349,7 @@ in width: parent.width height: 28 color: masterMuteMa.containsMouse ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } radius: 4 Text { @@ -1485,6 +1499,7 @@ in width: parent.width height: 28 color: disconnectMouse.containsMouse ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } radius: 4 Text { @@ -1534,6 +1549,7 @@ in width: 220 height: 32 color: netItemMouse.containsMouse ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } radius: 4 Row { @@ -1674,6 +1690,7 @@ in color: batteryWidget.powerProfile === modelData.name ? Theme.base02 : profMouse.containsMouse ? Theme.base01 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } border.width: batteryWidget.powerProfile === modelData.name ? 1 : 0 border.color: Theme.base03 @@ -1831,6 +1848,7 @@ in width: 28; height: 28; radius: 6 anchors.left: parent.left color: calPrevMa.containsMouse ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } Text { anchors.centerIn: parent text: "\u{f0141}" @@ -1865,6 +1883,7 @@ in width: 28; height: 28; radius: 6 anchors.right: parent.right color: calNextMa.containsMouse ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } Text { anchors.centerIn: parent text: "\u{f0142}" @@ -2063,6 +2082,7 @@ in required property var modelData width: 28; height: 28; radius: 14 color: mediaBtnMa.containsMouse ? Theme.base02 : "transparent" + Behavior on color { ColorAnimation { duration: 120 } } Text { anchors.centerIn: parent text: mediaBtn.modelData.glyph @@ -2199,6 +2219,7 @@ in height: actionText.height + 4 radius: 4 color: actionMa.containsMouse ? Theme.base03 : Theme.base02 + Behavior on color { ColorAnimation { duration: 120 } } border.width: 1 border.color: Theme.base03 Text { @@ -2268,7 +2289,9 @@ in Connections { target: bar.shellRoot function onNotificationReceived() { - if (toastItem.isPrimary) { + // No toast while the calendar popup is open — the + // notification list is already on screen there. + if (toastItem.isPrimary && !calPopup.visible) { toastItem.showToast(bar.shellRoot.latestNotification); } } @@ -2402,7 +2425,7 @@ in } Behavior on height { - NumberAnimation { duration: 220; easing.type: Easing.OutCubic } + NumberAnimation { duration: 280; easing.type: Easing.OutExpo } } Column { @@ -2446,6 +2469,7 @@ in height: toastActionText.height + 6 radius: 4 color: toastActionMa.containsMouse ? Theme.base02 : Theme.base01 + Behavior on color { ColorAnimation { duration: 120 } } border.width: 1 border.color: Theme.base02 Text {