diff --git a/quickshell/Common/ListViewTransitions.qml b/quickshell/Common/ListViewTransitions.qml index 64bef9a1d..1135e60f6 100644 --- a/quickshell/Common/ListViewTransitions.qml +++ b/quickshell/Common/ListViewTransitions.qml @@ -32,21 +32,12 @@ Singleton { PauseAnimation { duration: Math.max(0, Math.min(addTransition.ViewTransition.index - (addTransition.ViewTransition.targetIndexes[0] ?? 0), root._staggerCap)) * root._staggerMs } - ParallelAnimation { - DankAnim { - property: "opacity" - from: 0 - to: 1 - duration: Theme.expressiveDurations.fast - easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel - } - DankAnim { - property: "y" - from: addTransition.ViewTransition.destination.y + Theme.spacingS - to: addTransition.ViewTransition.destination.y - duration: Theme.expressiveDurations.fast - easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel - } + DankAnim { + property: "opacity" + from: 0 + to: 1 + duration: Theme.expressiveDurations.fast + easing.bezierCurve: Theme.expressiveCurves.emphasizedDecel } } } diff --git a/quickshell/Modals/Clipboard/ClipboardContent.qml b/quickshell/Modals/Clipboard/ClipboardContent.qml index 8228a979a..eaf341dcd 100644 --- a/quickshell/Modals/Clipboard/ClipboardContent.qml +++ b/quickshell/Modals/Clipboard/ClipboardContent.qml @@ -217,20 +217,6 @@ Item { pressDelay: 0 flickableDirection: Flickable.VerticalFlick - states: [ - State { - name: "snap" - when: Theme.snapListModelChanges - PropertyChanges { - target: clipboardListView - add: null - remove: null - displaced: null - move: null - } - } - ] - function ensureVisible(index) { if (index < 0 || index >= count) { return; @@ -293,20 +279,6 @@ Item { pressDelay: 0 flickableDirection: Flickable.VerticalFlick - states: [ - State { - name: "snap" - when: Theme.snapListModelChanges - PropertyChanges { - target: savedListView - add: null - remove: null - displaced: null - move: null - } - } - ] - function ensureVisible(index) { if (index < 0 || index >= count) { return; diff --git a/quickshell/Modals/DankLauncherV2/DankLauncherV2ModalSpotlight.qml b/quickshell/Modals/DankLauncherV2/DankLauncherV2ModalSpotlight.qml index 4e615a8ce..b5f6bb126 100644 --- a/quickshell/Modals/DankLauncherV2/DankLauncherV2ModalSpotlight.qml +++ b/quickshell/Modals/DankLauncherV2/DankLauncherV2ModalSpotlight.qml @@ -362,11 +362,12 @@ Item { WlrLayershell.exclusiveZone: -1 WlrLayershell.keyboardFocus: KeyboardFocus.keyboardFocus(keyboardActive, null) + // Anchored top+bottom: dynamic layer-surface resizes misbehave on some compositors anchors { top: true left: true right: root.useSingleWindow - bottom: root.useSingleWindow + bottom: true } WlrLayershell.margins { @@ -377,7 +378,6 @@ Item { } implicitWidth: root.useSingleWindow ? 0 : root.windowWidth - implicitHeight: root.useSingleWindow ? 0 : root.windowHeight mask: Region { item: inputMask diff --git a/quickshell/Modules/ProcessList/ProcessesView.qml b/quickshell/Modules/ProcessList/ProcessesView.qml index e6bee87b7..1c9bb703f 100644 --- a/quickshell/Modules/ProcessList/ProcessesView.qml +++ b/quickshell/Modules/ProcessList/ProcessesView.qml @@ -301,20 +301,6 @@ Item { clip: true spacing: Theme.spacingXXS - states: [ - State { - name: "snap" - when: Theme.snapListModelChanges - PropertyChanges { - target: processListView - add: null - remove: null - displaced: null - move: null - } - } - ] - model: ScriptModel { values: root.cachedProcesses objectProp: "pid" diff --git a/quickshell/Widgets/DankListView.qml b/quickshell/Widgets/DankListView.qml index 41bdc9b68..c4770b22e 100644 --- a/quickshell/Widgets/DankListView.qml +++ b/quickshell/Widgets/DankListView.qml @@ -28,6 +28,70 @@ ListView { displaced: ListViewTransitions.displaced move: ListViewTransitions.move + // QQmlDelegateModel can release a delegate back to its cache without hiding it, + // leaving a stale row painted over live ones. Hide anything the view no longer claims. + Connections { + target: listView.model?.objectName !== undefined ? listView.model : null + ignoreUnknownSignals: true + function onRowsInserted() { + orphanSweep.arm(); + } + function onRowsRemoved() { + orphanSweep.arm(); + } + function onRowsMoved() { + orphanSweep.arm(); + } + function onModelReset() { + orphanSweep.arm(); + } + } + + FrameAnimation { + id: orphanSweep + + property int frames: 0 + + function arm() { + frames = 0; + running = true; + } + + onTriggered: { + const kids = listView.contentItem.children; + const rows = []; + for (let i = 0; i < kids.length; i++) { + const c = kids[i]; + if (!c || c.index === undefined) + continue; + const claimed = listView.itemAtIndex(c.index) === c; + if (claimed && !c.visible) { + c.visible = true; + continue; + } + if (c.visible) + rows.push({ + item: c, + claimed: claimed + }); + } + for (let a = 0; a < rows.length; a++) { + if (rows[a].claimed) + continue; + for (let b = 0; b < rows.length; b++) { + if (a === b || !rows[b].claimed) + continue; + if (Math.abs(rows[a].item.y - rows[b].item.y) < rows[b].item.height / 2) { + rows[a].item.visible = false; + break; + } + } + } + if (++frames >= 3) + running = false; + } + } + onMovementStarted: { isUserScrolling = true; vbar._scrollBarActive = true;