quickshell: stop launcher rows fading to random opacities

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 <noreply@anthropic.com>
This commit is contained in:
rope 2026-08-01 19:42:37 +01:00
parent 4b4ae52c65
commit a8eb76782c

View file

@ -2621,19 +2621,31 @@ in
highlightMoveVelocity: -1 highlightMoveVelocity: -1
highlightResizeDuration: 0 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 { move: Transition {
NumberAnimation { properties: "x,y"; duration: Theme.animContent; easing.type: Easing.OutExpo } NumberAnimation { properties: "x,y"; duration: Theme.animContent; easing.type: Easing.OutExpo }
} }
displaced: Transition { displaced: Transition {
NumberAnimation { properties: "x,y"; duration: Theme.animContent; easing.type: Easing.OutExpo } 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 { delegate: Item {
required property string appId required property string appId