@@ -36,6 +36,10 @@ export class MacOSScrollAccel implements ScrollAcceleration {
3636 private velocityHistory : number [ ] = [ ]
3737 private readonly historySize = 3
3838 private readonly streakTimeout = 150
39+ // some terminals send 2 or more ticks for each mouse wheel ticks, for example Ghostty, with a small delay between each, 3ms on averate.
40+ // We ignore these ticks otherwise they would cause faster acceleration to kick in
41+ // https://github.com/ghostty-org/ghostty/discussions/7577
42+ private readonly minTickInterval = 6
3943
4044 constructor (
4145 private opts : {
@@ -51,32 +55,30 @@ export class MacOSScrollAccel implements ScrollAcceleration {
5155 const maxMultiplier = this . opts . maxMultiplier ?? 6
5256
5357 const dt = this . lastTickTime ? now - this . lastTickTime : Infinity
54- this . lastTickTime = now
5558
56- // Reset streak if too much time has passed
57- if ( dt > this . streakTimeout ) {
59+ // Reset streak if too much time has passed or first tick
60+ if ( dt === Infinity || dt > this . streakTimeout ) {
61+ this . lastTickTime = now
5862 this . velocityHistory = [ ]
5963 return 1
6064 }
6165
62- // Track recent intervals
63- if ( dt !== Infinity ) {
64- this . velocityHistory . push ( dt )
65- if ( this . velocityHistory . length > this . historySize ) {
66- this . velocityHistory . shift ( )
67- }
66+ // Ignore ticks closer than minTickInterval (they're part of the same logical tick)
67+ if ( dt < this . minTickInterval ) {
68+ return 1
6869 }
6970
70- // Calculate average interval (lower = faster scrolling)
71- const avgInterval =
72- this . velocityHistory . length > 0
73- ? this . velocityHistory . reduce ( ( a , b ) => a + b , 0 ) / this . velocityHistory . length
74- : Infinity
71+ this . lastTickTime = now
7572
76- if ( avgInterval === Infinity ) {
77- return 1
73+
74+ this . velocityHistory . push ( dt )
75+ if ( this . velocityHistory . length > this . historySize ) {
76+ this . velocityHistory . shift ( )
7877 }
7978
79+ // Calculate average interval (lower = faster scrolling)
80+ const avgInterval = this . velocityHistory . reduce ( ( a , b ) => a + b , 0 ) / this . velocityHistory . length
81+
8082 // Convert interval to velocity: faster ticks = higher velocity
8183 // Normalize to a reference interval (e.g., 100ms = velocity of 1)
8284 const referenceInterval = 100
0 commit comments