true smooth scrolling: compatibility with a different encoding of absolute scrolling deltas in JetBrains Runtime

This commit is contained in:
Pavel Fatin
2017-01-30 22:35:45 +01:00
parent 847ad9d0d3
commit 77f144de67
@@ -15,39 +15,37 @@
*/
package com.intellij.ui.components;
import com.intellij.util.MethodInvocator;
import com.intellij.openapi.util.SystemInfo;
import java.awt.event.MouseWheelEvent;
/**
* Accessor for absolute scrolling delta in the
* <a href="https://github.com/JetBrains/jdk8u_jdk/commit/568f2dae82b0fe27b79ce6943071d89463758610">enhanced MouseWheelEvent</a>.
* <p>
* Should be paired up with our custom JRE (currently has has
* an <a href="https://github.com/JetBrains/jdk8u_jdk/commit/a3cb8807b148879e9c70a74a8a16c30a28991581">implementation</a> for Mac OS X).
* Accessor for absolute scrolling delta in enhanced MouseWheelEvent.
*/
class MouseWheelEventEx {
private static final MethodInvocator ourGetScrollingDeltaMethod = new MethodInvocator(false, MouseWheelEvent.class, "getScrollingDelta");
/**
* Returns scrolling delta as an absolute value (if available).
* <p>
* Returns 0.0 when scrolling delta is available only as a number of "clicks" or
* as a fraction of a "click".
* <p>
* The method returns natural numbers, however, for future extensibility,
* the return type is declared as {@code double}.
* Returns scrolling delta as an absolute value (if available). Requires JetBrains Runtime.
* <p>
* Some devices (e.g. high-precision touchpads) may report scrolling deltas
* in absolute values rather than in fractions of a "click". This data can be used,
* for example, to implement pixel-perfect scrolling (which cannot be
* implemented via the {@link MouseWheelEvent#getPreciseWheelRotation} method, as fractions
* of scrolling "units" cannot be reliably translated to pixel-precise deltas).
* <p>
* JetBrains Runtime currently uses <code>preciseWheelRotation = 0.1 * scrollingDelta</code>
* mapping in Mac OS to encode absolute scrolling deltas as relative ones.
* <p>
* That approach is suboptimal, because it:
* 1) produces different dynamics of relative deltas (in Mac OS there's no reliable linear mapping between those values),
* 2) makes handling of true relative deltas impossible (as there's no way to distinguish them from the encoded absolute ones).
* <p>
* Ideally, we need to implement a method of distinguishing between the two kinds of scrolling deltas.
*
* @param event the event
* @return negative values for scrolling up, positive values for scrolling down (natural numbers)
* @param e the event
* @return negative values for scrolling up, positive values for scrolling down
* 0.0 when absolute deltas are not supported or not available
*/
static double getScrollingDelta(MouseWheelEvent event) {
return ourGetScrollingDeltaMethod.isAvailable() ? (double)ourGetScrollingDeltaMethod.invoke(event) : 0.0D;
static double getScrollingDelta(MouseWheelEvent e) {
return SystemInfo.isJetbrainsJvm && SystemInfo.isMac ? 10.0D * e.getPreciseWheelRotation() : 0.0D;
}
}