From a8eb76782cc714b0f8a906fa91641ba26bc3a62b Mon Sep 17 00:00:00 2001 From: rope Date: Sat, 1 Aug 2026 19:42:37 +0100 Subject: [PATCH] quickshell: stop launcher rows fading to random opacities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The results ListView had add/remove transitions animating opacity and scale on the delegate root. The model is re-diffed on every keystroke, so a row part-way through a fade frequently survived the next pass as a move instead of a remove — and move animates x,y only, leaving the half-finished opacity permanently unrestored. Rows accumulated stuck at arbitrary opacities depending on typing speed, which read as the result colours randomly fading. Dropped both fades. x,y stay animated because the view re-asserts them on every layout, so an interrupted slide self-corrects; opacity and scale have no such backstop. Comment records that a future fade belongs on a child item, not the root the view recycles. Co-Authored-By: Claude Opus 5 --- settings/quickshell.nix | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/settings/quickshell.nix b/settings/quickshell.nix index 71d7ab3..51641bd 100644 --- a/settings/quickshell.nix +++ b/settings/quickshell.nix @@ -2621,19 +2621,31 @@ in highlightMoveVelocity: -1 highlightResizeDuration: 0 + // Only x,y are animated, and that is deliberate. + // There used to be add/remove transitions + // fading `opacity` and `scale` on the delegate + // root, and they corrupted the list: the model + // is re-diffed on EVERY keystroke, so a row + // part-way through a fade often survives the + // next pass as a move rather than a + // remove — and move animates x,y only, so the + // half-finished opacity was never restored. + // Rows accumulated stuck at 0.3, 0.6, 1.0 + // depending on typing speed, which looked like + // the colours randomly fading. + // + // x,y are safe to animate because the view + // re-asserts them on every layout, so an + // interrupted slide self-corrects. opacity and + // scale have no such backstop. If a fade is + // ever wanted back, animate a child item, not + // the root the view recycles. move: Transition { NumberAnimation { properties: "x,y"; duration: Theme.animContent; easing.type: Easing.OutExpo } } displaced: Transition { NumberAnimation { properties: "x,y"; duration: Theme.animContent; easing.type: Easing.OutExpo } } - add: Transition { - NumberAnimation { property: "opacity"; from: 0; to: 1; duration: Theme.animContent } - NumberAnimation { property: "scale"; from: 0.92; to: 1; duration: Theme.animContent; easing.type: Easing.OutExpo } - } - remove: Transition { - NumberAnimation { property: "opacity"; to: 0; duration: 100 } - } delegate: Item { required property string appId