intellij-community
intellij-community copied to clipboard
Fix touchpad smooth scrolling [IDEA-131174]
I know there have been previous attempts to fix this issue before, including the many experimental Registry flags under idea.true.smooth.scrolling, however, none of these have managed to properly fix this problem, and any time I need to use IntelliJ on my laptop without a mouse this poor UX drives me mad.
IntelliJ - Smooth Scrolling.webm
I've tried to make the smallest possible fix, which perfectly works on my Windows 10 laptop, and shouldn't interfere with regular mouse scrolling in any way. I'm however unable to verify if this fix helps to mitigate this issue on MacOS devices (albeit it reasonably should).
Some implementation considerations:
- In Windows, the
MouseWheelEvent#getPreciseWheelRotationproperly returns a fractional wheel delta, except when zooming with a pinch gesture (Ctrl + Wheel), in which case, theMouseWheelEventis accumulated until it reaches a full delta unit (unfortunately, the cause of this is Windows itself, touchpad pinch gestures are a separate event, which AWT doesn't map toMouseWheelEvent). - The added
verticalCumulativeDeltaandhorizontalCumulativeDeltafields are necessary. Otherwise, as can be tested by commenting lineMouseWheelSmoothScroll.java:60, scrolling slowly in panels where the scrollable unit increment is small enough such that the resulting delta is smaller than a whole pixel (such as scrolling horizontally in the Project view) would result in an unresponsive UX, that would only respond after reaching a certain minimal speed, and decimals would be lost on each event, regardless of speed. This breaks the linearity of scrolling back and forth, and can drive a user mad too. - To support proper touchpad smooth scrolling it's also necessary to suppress the mouse smooth scrolling animator when a touchpad is being used. This is detected by the use of wheel delta values smaller than a whole unit (since any other device that produced fractional wheel events would also probably prefer having no artificial smoothing). Adding inertia to the touchpad scrolling results in a laggy feeling, extremely frustrating from the user perspective.
- There's no need to implement fling gestures, since Windows (and I assume MacOS) do this already (as janky as it may be). With this fix, flinging the touchpad behaves as it'd be expected.
MouseWheelSmoothScroll$ScrollAnimationSettings#SETTINGShas been renamed toDEFAULT, since it's a more sensible name after addingMouseWheelSmoothScroll$ScrollAnimationSettings#NO_ANIMATION. As this enum is package private and the only usage is within the code that has been modified, no concerns justified keeping the original name (but I'm of course willing to revert it if preferred).- No changes have been made to the public platform API. This fix should have no effect on backwards compatibility.
Additionally, I've also extended this fix to the image viewer in a separate commit.
Unfortunately, as already mentioned, at least in Windows, touchpad pinch gestures don't generate fractional delta wheel events as scroll gestures do, so the only way to smoothly zoom in the image viewer with this fix is by holding the Ctrl key while scrolling with the touchpad. However, should that ever change in the future, this fix would make pinch gestures zoom smoothly.
I'm willing to make any necessary changes to get this accepted, but please consider accepting this fix. Jagged touchpad scrolling makes for very poor UX. Feedback is welcome.
After some investigation I've found that the source of the accumulation of wheel events for pinch gestures is actually Windows, since even native applications receive them accumulated, so it's not an AWT issue as I thought initially, although a solution could be implemented there. I've updated the description to reflect this.