touchpad: improve scroll speed handling for touchpad (#1781)

This commit is contained in:
end-4
2025-08-07 23:46:39 +07:00
committed by GitHub
7 changed files with 72 additions and 24 deletions
@@ -266,7 +266,6 @@ Singleton {
easing.bezierCurve: root.animation.elementMoveFast.bezierCurve easing.bezierCurve: root.animation.elementMoveFast.bezierCurve
}} }}
} }
property QtObject clickBounce: QtObject { property QtObject clickBounce: QtObject {
property int duration: 200 property int duration: 200
property int type: Easing.BezierSpline property int type: Easing.BezierSpline
@@ -279,7 +278,7 @@ Singleton {
}} }}
} }
property QtObject scroll: QtObject { property QtObject scroll: QtObject {
property int duration: 400 property int duration: 200
property int type: Easing.BezierSpline property int type: Easing.BezierSpline
property list<real> bezierCurve: animationCurves.standardDecel property list<real> bezierCurve: animationCurves.standardDecel
} }
@@ -181,6 +181,14 @@ Singleton {
property list<string> ignoredAppRegexes: [] property list<string> ignoredAppRegexes: []
} }
property JsonObject interactions: JsonObject {
property JsonObject scrolling: JsonObject {
property int mouseScrollDeltaThreshold: 120 // delta >= this then it gets detected as mouse scroll rather than touchpad
property int mouseScrollFactor: 120
property int touchpadScrollFactor: 450
}
}
property JsonObject language: JsonObject { property JsonObject language: JsonObject {
property JsonObject translator: JsonObject { property JsonObject translator: JsonObject {
property string engine: "auto" // Run `trans -list-engines` for available engines. auto should use google property string engine: "auto" // Run `trans -list-engines` for available engines. auto should use google
@@ -63,7 +63,7 @@ Item {
Layout.rightMargin: dialogPadding Layout.rightMargin: dialogPadding
} }
ListView { StyledListView {
id: choiceListView id: choiceListView
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
@@ -71,9 +71,6 @@ Item {
currentIndex: root.defaultChoice !== undefined ? root.items.indexOf(root.defaultChoice) : -1 currentIndex: root.defaultChoice !== undefined ? root.items.indexOf(root.defaultChoice) : -1
spacing: 6 spacing: 6
maximumFlickVelocity: 3500
boundsBehavior: Flickable.DragOverBounds
model: ScriptModel { model: ScriptModel {
id: choiceModel id: choiceModel
} }
@@ -1,6 +1,35 @@
import QtQuick import QtQuick
import qs.modules.common
Flickable { Flickable {
id: root
maximumFlickVelocity: 3500 maximumFlickVelocity: 3500
boundsBehavior: Flickable.DragOverBounds 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
MouseArea {
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;
var targetY = root.contentY - delta * scrollFactor;
targetY = Math.max(0, Math.min(targetY, root.contentHeight - root.height));
root.contentY = targetY;
}
}
Behavior on contentY {
NumberAnimation {
id: scrollAnim
duration: Appearance.animation.scroll.duration
easing.type: Appearance.animation.scroll.type
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
}
}
} }
@@ -15,6 +15,10 @@ ListView {
property real dragDistance: 0 property real dragDistance: 0
property bool popin: true property bool popin: true
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
function resetDrag() { function resetDrag() {
root.dragIndex = -1 root.dragIndex = -1
root.dragDistance = 0 root.dragDistance = 0
@@ -23,6 +27,29 @@ ListView {
maximumFlickVelocity: 3500 maximumFlickVelocity: 3500
boundsBehavior: Flickable.DragOverBounds boundsBehavior: Flickable.DragOverBounds
MouseArea {
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;
var targetY = root.contentY - delta * scrollFactor;
targetY = Math.max(0, Math.min(targetY, root.contentHeight - root.height));
root.contentY = targetY;
}
}
Behavior on contentY {
NumberAnimation {
id: scrollAnim
duration: Appearance.animation.scroll.duration
easing.type: Appearance.animation.scroll.type
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
}
}
add: Transition { add: Transition {
animations: [ animations: [
Appearance?.animation.elementMove.numberAnimation.createObject(this, { Appearance?.animation.elementMove.numberAnimation.createObject(this, {
@@ -282,6 +282,9 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\)
spacing: 10 spacing: 10
popin: false popin: false
touchpadScrollFactor: Config.options.interactions.scrolling.touchpadScrollFactor * 1.4
mouseScrollFactor: Config.options.interactions.scrolling.mouseScrollFactor * 1.4
property int lastResponseLength: 0 property int lastResponseLength: 0
clip: true clip: true
@@ -296,15 +299,6 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\)
add: null // Prevent function calls from being janky add: null // Prevent function calls from being janky
Behavior on contentY {
NumberAnimation {
id: scrollAnim
duration: Appearance.animation.scroll.duration
easing.type: Appearance.animation.scroll.type
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
}
}
model: ScriptModel { model: ScriptModel {
values: Ai.messageIDs.filter(id => { values: Ai.messageIDs.filter(id => {
const message = Ai.messageByID[id]; const message = Ai.messageByID[id];
@@ -137,6 +137,9 @@ Item {
anchors.fill: parent anchors.fill: parent
spacing: 10 spacing: 10
touchpadScrollFactor: Config.options.interactions.scrolling.touchpadScrollFactor * 1.4
mouseScrollFactor: Config.options.interactions.scrolling.mouseScrollFactor * 1.4
property int lastResponseLength: 0 property int lastResponseLength: 0
clip: true clip: true
@@ -149,15 +152,6 @@ Item {
} }
} }
Behavior on contentY {
NumberAnimation {
id: scrollAnim
duration: Appearance.animation.scroll.duration
easing.type: Appearance.animation.scroll.type
easing.bezierCurve: Appearance.animation.scroll.bezierCurve
}
}
model: ScriptModel { model: ScriptModel {
values: { values: {
if(root.responses.length > booruResponseListView.lastResponseLength) { if(root.responses.length > booruResponseListView.lastResponseLength) {