diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart index 628b27fb2..675a95e42 100644 --- a/flutter/lib/models/input_model.dart +++ b/flutter/lib/models/input_model.dart @@ -348,6 +348,12 @@ class InputModel { final _trackpadAdjustPeerLinux = 0.06; // This is an experience value. final _trackpadAdjustMacToWin = 2.50; + // Ignore directional locking for very small deltas on both axes (including + // tiny single-axis movement) to avoid over-filtering near zero. + static const double _trackpadAxisNoiseThreshold = 0.2; + // Lock to dominant axis only when one axis is clearly stronger. + // 1.6 means the dominant axis must be >= 60% larger than the other. + static const double _trackpadAxisLockRatio = 1.6; int _trackpadSpeed = kDefaultTrackpadSpeed; double _trackpadSpeedInner = kDefaultTrackpadSpeed / 100.0; var _trackpadScrollUnsent = Offset.zero; @@ -1172,6 +1178,7 @@ class InputModel { if (isMacOS && peerPlatform == kPeerPlatformWindows) { delta *= _trackpadAdjustMacToWin; } + delta = _filterTrackpadDeltaAxis(delta); _trackpadLastDelta = delta; var x = delta.dx.toInt(); @@ -1204,6 +1211,24 @@ class InputModel { } } + Offset _filterTrackpadDeltaAxis(Offset delta) { + final absDx = delta.dx.abs(); + final absDy = delta.dy.abs(); + // Keep diagonal intent when movement is tiny on both axes. + if (absDx < _trackpadAxisNoiseThreshold && + absDy < _trackpadAxisNoiseThreshold) { + return delta; + } + // Dominant-axis lock to reduce accidental cross-axis scrolling noise. + if (absDy >= absDx * _trackpadAxisLockRatio) { + return Offset(0, delta.dy); + } + if (absDx >= absDy * _trackpadAxisLockRatio) { + return Offset(delta.dx, 0); + } + return delta; + } + void _scheduleFling(double x, double y, int delay) { if (isViewCamera) return; if ((x == 0 && y == 0) || _stopFling) {