I'm having a lot of trouble with circular scrolling on my new ThinkPad 21MN005QUS. Circular scrolling often gets interrupted at some random time after starting, at which point the mouse starts moving normally and I have to reinitiate circular scrolling. This only happens when initiating from the left, top, or right edges, and only after recently using the TrackPoint mouse (isometric joystick). The bottom edge always works fine, as does using only the touchpad and touchscreen but never TrackPoint.
I recompiled xf86-input-synaptics 1.10.0 with -DDEBUG and ran Xorg with -logverbose 7. This produces output such as the following: [ 11782.192] (II) SetTapState - 0 -> 1 (millis:11782193) [ 11782.192] (II) circular scroll detected on edge [ 11782.372] (II) SetMovingState - 0 -> 1 center at 3520/971 (millis:11782373) [ 11782.372] (II) SetTapState - 1 -> 2 (millis:11782373) [ 11782.855] (II) SetMovingState - 1 -> 0 center at 3219/524 (millis:11782856) [ 11782.855] (II) SetTapState - 2 -> 0 (millis:11782856) [ 11782.855] (II) cicular scroll off [ 11782.862] (II) SetTapState - 0 -> 1 (millis:11782863) [ 11783.042] (II) SetMovingState - 0 -> 1 center at 3107/483 (millis:11783043) [ 11783.042] (II) SetTapState - 1 -> 2 (millis:11783043) [ 11783.381] (II) SetMovingState - 1 -> 0 center at 3014/467 (millis:11783382) [ 11783.381] (II) SetTapState - 2 -> 0 (millis:11783382) As far as the driver knows, after a half second of scrolling, I lifted my finger off the touchpad and then touched it again seven milliseconds later, which is why it turns to ordinary mouse movement. Adding more arguments to HandleScrolling() and putting them in the log, I see that at the time of "cicular scroll off" [sic], I'm getting finger==FS_UNTOUCHED and from_timer==FALSE. Unless initiating from the bottom edge, this always happens the first time I attempt circular scrolling after using the TrackPoint, then usually again the next several times I attempt scrolling. If I try enough times, without any intervening use of the TrackPoint, then it becomes stable and works every time, even when I also do some touchpad mouse movements (including successfully scrolling from the bottom edge). I haven't been able to determine the precise conditions for failure. In some respects, it's as if there's some timeout following my last use of the TrackPoint during which it periodically reasserts its dominance and interrupts the touchpad. Except, that doesn't make sense in light of the fact that it works from the bottom edge. If I stick to using the touchpad or touchscreen, never bumping the TrackPoint, or if I always initiate from the bottom edge, scrolling works every time. Also, it doesn't make a difference if I do brief or extended touchpad mouse movements between my last use of the TrackPoint and starting circular scrolling; the first (and usually several subsequent) attempts at scrolling are still interrupted. It doesn't seem like the fault lies in the Xorg Synaptics driver. The code looks fine to me, and most especially it shouldn't have any potential for interaction with the TrackPoint. Perhaps there's an issue with the kernel, or even the I2C controller. Looking at the output of evtest, I see: Event: time 1742094311.913760, -------------- SYN_REPORT ------------ Event: time 1742094311.913762, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1 Event: time 1742094311.913762, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 1742094311.913762, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 0 Event: time 1742094311.913762, -------------- SYN_REPORT ------------ Event: time 1742094311.920697, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 1097 Event: time 1742094311.920697, type 3 (EV_ABS), code 55 (ABS_MT_TOOL_TYPE), value 0 Event: time 1742094311.920697, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 1832 Event: time 1742094311.920697, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 312 Event: time 1742094311.920697, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 1742094311.920697, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 1 Event: time 1742094311.920697, type 3 (EV_ABS), code 0 (ABS_X), value 1832 Event: time 1742094311.920697, type 3 (EV_ABS), code 1 (ABS_Y), value 312 Event: time 1742094311.920697, type 4 (EV_MSC), code 5 (MSC_TIMESTAMP), value 1903900 This shows a finger release and repress within the span of just under seven milliseconds, which sounds awfully familiar. But, it's very hard to think this is a defect in the touchpad, given that it works perfectly if I never use the TrackPoint or always start from the bottom edge. Wondering if it's releasing and repressing more than I realize, I tried piping the output of evtest to grep 'BTN_TOUCH.*0', but sure enough, this only prints when (1) I truly lift my finger or (2) once shortly after I initiate circular scrolling from any edge other than the bottom, after recently using the TrackPoint. This makes me think the kernel driver somehow knows it's in circular scrolling mode, or else I'd be seeing spurious releases at other times. Except, the kernel driver source doesn't mention circular scrolling and doesn't know about edge zones. Super confusing to me. I'd blame the touchpad firmware, except it wouldn't have a reason to know about the TrackPoint. I can't very well blame the I2C controller since it's integrated in the CPU (I think... it's Meteor Lake-P) and shouldn't care about the meaning of the data it's passing along. Where to go from here? I returned a different laptop and bought this one at a higher price specifically because the other one's mouse was terrible, and it took a month and a half to ship, so I'm really not keen on accepting anything less than perfection from this new mouse. I've considered putting in some bodge to smooth over very brief interruptions, but this would be a very crude hack with the side effect of delaying legitimate releases. Maybe only ignore brief release/repress while in the midst of circular scrolling. I thought also about whether this change should go into the kernel or Xorg driver. The mere fact that I can argue either way about the merits of the former is itself an argument against the former, plus doing it in the latter would allow release/repress to be ignored during scrolling and at no other time. To be clear: even if such a change would not tolerable upstream, it would still be beneficial for me to make for my own use. That being said, if given the choice, I'd rather do it in a way that could be accepted upstream than not, so I wouldn't have to continually repatch and rebuild my X server for as long as I own this laptop. Note to search engines indexing this email: circular scrolling is also known as chiral scrolling. I've found a lot of material by searching for that term. -- Andy Goth | <andrew.m.goth/at/gmail/dot/com>