< prev index next >

src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java

Print this page

        

@@ -42,10 +42,12 @@
 final class CPlatformResponder {
 
     private final PlatformEventNotifier eventNotifier;
     private final boolean isNpapiCallback;
     private int lastKeyPressCode = KeyEvent.VK_UNDEFINED;
+    private final DeltaAccumulator deltaAccumulatorX = new DeltaAccumulator();
+    private final DeltaAccumulator deltaAccumulatorY = new DeltaAccumulator();
 
     CPlatformResponder(final PlatformEventNotifier eventNotifier,
                        final boolean isNpapiCallback) {
         this.eventNotifier = eventNotifier;
         this.isNpapiCallback = isNpapiCallback;

@@ -87,41 +89,41 @@
     /**
      * Handles scroll events.
      */
     void handleScrollEvent(final int x, final int y, final int absX,
                            final int absY, final int modifierFlags,
-                           final double deltaX, final double deltaY) {
+                           final double deltaX, final double deltaY,
+                           final int scrollPhase) {
         int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
         final boolean isShift = (jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
 
+        int roundDeltaX = deltaAccumulatorX.getRoundedDelta(deltaX, scrollPhase);
+        int roundDeltaY = deltaAccumulatorY.getRoundedDelta(deltaY, scrollPhase);
+
         // Vertical scroll.
-        if (!isShift && deltaY != 0.0) {
-            dispatchScrollEvent(x, y, absX, absY, jmodifiers, deltaY);
+        if (!isShift && (deltaY != 0.0 || roundDeltaY != 0)) {
+            dispatchScrollEvent(x, y, absX, absY, jmodifiers, roundDeltaY, deltaY);
         }
         // Horizontal scroll or shirt+vertical scroll.
         final double delta = isShift && deltaY != 0.0 ? deltaY : deltaX;
-        if (delta != 0.0) {
+        final int roundDelta = isShift && roundDeltaY != 0.0 ? roundDeltaY : roundDeltaX;
+        if (delta != 0.0 || roundDelta != 0) {
             jmodifiers |= InputEvent.SHIFT_DOWN_MASK;
-            dispatchScrollEvent(x, y, absX, absY, jmodifiers, delta);
+            dispatchScrollEvent(x, y, absX, absY, jmodifiers, roundDelta, delta);
         }
     }
 
     private void dispatchScrollEvent(final int x, final int y, final int absX,
                                      final int absY, final int modifiers,
-                                     final double delta) {
+                                     final int roundDelta, final double delta) {
         final long when = System.currentTimeMillis();
         final int scrollType = MouseWheelEvent.WHEEL_UNIT_SCROLL;
         final int scrollAmount = 1;
-        int wheelRotation = (int) delta;
-        int signum = (int) Math.signum(delta);
-        if (signum * delta < 1) {
-            wheelRotation = signum;
-        }
         // invert the wheelRotation for the peer
         eventNotifier.notifyMouseWheelEvent(when, x, y, absX, absY, modifiers,
                                             scrollType, scrollAmount,
-                                            -wheelRotation, -delta, null);
+                                            -roundDelta, -delta, null);
     }
 
     /**
      * Handles key events.
      */

@@ -258,6 +260,49 @@
     }
 
     void handleWindowFocusEvent(boolean gained, LWWindowPeer opposite) {
         eventNotifier.notifyActivation(gained, opposite);
     }
+
+    static class DeltaAccumulator {
+
+        static final double MIN_THRESHOLD = 0.1;
+        static final double MAX_THRESHOLD = 0.8;
+        double accumulatedDelta;
+
+        int getRoundedDelta(double delta, int scrollPhase) {
+
+            int roundDelta = (int) Math.round(delta);
+
+            if (scrollPhase == NSEvent.SCROLL_PHASE_UNSUPPORTED) { // mouse wheel
+                if (roundDelta == 0 && delta != 0) {
+                    roundDelta = delta > 0 ? 1 : -1;
+                }
+            } else { // trackpad
+                boolean begin = scrollPhase == NSEvent.SCROLL_PHASE_BEGAN;
+                boolean end = scrollPhase == NSEvent.SCROLL_MASK_PHASE_ENDED
+                        || scrollPhase == NSEvent.SCROLL_MASK_PHASE_CANCELLED;
+
+                if (begin) {
+                    accumulatedDelta = 0;
+                }
+
+                accumulatedDelta += delta;
+
+                double absAccumulatedDelta = Math.abs(accumulatedDelta);
+                if (absAccumulatedDelta > MAX_THRESHOLD) {
+                    roundDelta = (int) Math.round(accumulatedDelta);
+                    accumulatedDelta -= roundDelta;
+                }
+
+                if (end) {
+                    if (roundDelta == 0 && absAccumulatedDelta > MIN_THRESHOLD) {
+                        roundDelta = accumulatedDelta > 0 ? 1 : -1;
+                    }
+                    accumulatedDelta = 0;
+                }
+            }
+
+            return roundDelta;
+        }
+    }
 }
< prev index next >