// StyledFlickable.qml from end-4 https://github.com/end-4/dots-hyprland/blob/main/.config/quickshell/ii/modules/common/widgets/StyledFlickable.qml import QtQuick import qs.common Flickable { id: root maximumFlickVelocity: 3500 boundsBehavior: Flickable.DragOverBounds property real touchpadScrollFactor: Config?.options.interactions.scrolling.touchpadScrollFactor ?? 100 property real mouseScrollFactor: Config?.options.interactions.scrolling.mouseScrollFactor ?? 50 property real mouseScrollDeltaThreshold: Config?.options.interactions.scrolling.mouseScrollDeltaThreshold ?? 120 property real scrollTargetY: 0 MouseArea { visible: Config?.options.interactions.scrolling.fasterTouchpadScroll anchors.fill: parent acceptedButtons: Qt.NoButton onWheel: function(wheelEvent) { const delta = wheelEvent.angleDelta.y / root.mouseScrollDeltaThreshold; // The angleDelta.y of a touchpad is usually small and continuous, // while that of a mouse wheel is typically in multiples of ±120. var scrollFactor = Math.abs(wheelEvent.angleDelta.y) >= root.mouseScrollDeltaThreshold ? root.mouseScrollFactor : root.touchpadScrollFactor; const maxY = Math.max(0, root.contentHeight - root.height); const base = scrollAnim.running ? root.scrollTargetY : root.contentY; var targetY = Math.max(0, Math.min(base - delta * scrollFactor, maxY)) } } Behavior on contentY { NumberAnimation { id: scrollAnim duration: Appearance.animation.scroll.duration easing.type: Appearance.animation.scroll.type easing.bezierCurve: Appearance.animation.scroll.bezierCurve } } // to keep target synced when not animating onContentYChanged: { if (!scrollAnim.running) { root.scrollTargetY = root.contentY; } } }