fix(clients/android): 3-finger stats tap — re-anchor the scroll centroid on pointer-count changes
The two-or-more-finger scroll path measured its centroid across a VARYING pointer count: real fingers never land (or lift) in the same input frame, so the 2→3 transition moved the centroid far past SCROLL_DIV, emitted a phantom wheel tick to the host, and set `moved` — which disqualified the not-moved tap classification and made the advertised 3-finger stats-cycle tap unreachable on real hardware (two-finger right-click survived only because its anchor never crossed a count change). Re-anchor whenever the finger count changes; genuine two-finger scrolling is measured between same-count frames exactly as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -127,6 +127,7 @@ internal suspend fun PointerInputScope.streamTouchInput(
|
|||||||
var moved = false
|
var moved = false
|
||||||
var maxFingers = 1
|
var maxFingers = 1
|
||||||
var scrolling = false
|
var scrolling = false
|
||||||
|
var scrollCount = 0 // pointer count the scroll centroid is anchored at
|
||||||
var prevCx = startX
|
var prevCx = startX
|
||||||
var prevCy = startY
|
var prevCy = startY
|
||||||
var upTime = down.uptimeMillis
|
var upTime = down.uptimeMillis
|
||||||
@@ -149,11 +150,18 @@ internal suspend fun PointerInputScope.streamTouchInput(
|
|||||||
if (pressed.size > maxFingers) maxFingers = pressed.size
|
if (pressed.size > maxFingers) maxFingers = pressed.size
|
||||||
|
|
||||||
if (pressed.size >= 2) {
|
if (pressed.size >= 2) {
|
||||||
// Two fingers → scroll by the centroid delta; never move the cursor.
|
// Two+ fingers → scroll by the centroid delta; never move the cursor.
|
||||||
val cx = (pressed.sumOf { it.position.x.toDouble() } / pressed.size).toFloat()
|
val cx = (pressed.sumOf { it.position.x.toDouble() } / pressed.size).toFloat()
|
||||||
val cy = (pressed.sumOf { it.position.y.toDouble() } / pressed.size).toFloat()
|
val cy = (pressed.sumOf { it.position.y.toDouble() } / pressed.size).toFloat()
|
||||||
if (!scrolling) {
|
// (Re-)anchor whenever the finger COUNT changes, not just on scroll start: the
|
||||||
|
// centroid of three fingers sits far from the centroid of two, and real fingers
|
||||||
|
// never land (or lift) in the same input frame — so the 2→3 transition would
|
||||||
|
// otherwise read as a scroll notch, sending a phantom wheel tick to the host AND
|
||||||
|
// setting `moved`, which disqualified the tap classification below and made the
|
||||||
|
// 3-finger stats tap unreachable on real hardware.
|
||||||
|
if (!scrolling || pressed.size != scrollCount) {
|
||||||
scrolling = true
|
scrolling = true
|
||||||
|
scrollCount = pressed.size
|
||||||
prevCx = cx
|
prevCx = cx
|
||||||
prevCy = cy
|
prevCy = cy
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user