8173876: Fast precise scrolling and DeltaAccumulator fix for macOS Sierra 10.12.2
Reviewed-by: serb, alexsch
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Wed Feb 08 19:22:20 2017 +0400
@@ -265,9 +265,8 @@
static class DeltaAccumulator {
- static final double MIN_THRESHOLD = 0.1;
- static final double MAX_THRESHOLD = 0.5;
double accumulatedDelta;
+ boolean accumulate;
int getRoundedDelta(double delta, int scrollPhase) {
@@ -278,25 +277,23 @@
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) {
+ if (scrollPhase == NSEvent.SCROLL_PHASE_BEGAN) {
accumulatedDelta = 0;
+ accumulate = true;
}
-
- accumulatedDelta += delta;
+ else if (scrollPhase == NSEvent.SCROLL_PHASE_MOMENTUM_BEGAN) {
+ accumulate = true;
+ }
+ if (accumulate) {
- double absAccumulatedDelta = Math.abs(accumulatedDelta);
- if (absAccumulatedDelta > MAX_THRESHOLD) {
+ accumulatedDelta += delta;
+
roundDelta = (int) Math.round(accumulatedDelta);
+
accumulatedDelta -= roundDelta;
- }
- if (end) {
- if (roundDelta == 0 && absAccumulatedDelta > MIN_THRESHOLD) {
- roundDelta = accumulatedDelta > 0 ? 1 : -1;
+ if (scrollPhase == NSEvent.SCROLL_PHASE_ENDED) {
+ accumulate = false;
}
}
}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java Wed Feb 08 19:22:20 2017 +0400
@@ -36,8 +36,8 @@
static final int SCROLL_PHASE_UNSUPPORTED = 1;
static final int SCROLL_PHASE_BEGAN = 2;
static final int SCROLL_PHASE_CONTINUED = 3;
- static final int SCROLL_MASK_PHASE_CANCELLED = 4;
- static final int SCROLL_MASK_PHASE_ENDED = 5;
+ static final int SCROLL_PHASE_MOMENTUM_BEGAN = 4;
+ static final int SCROLL_PHASE_ENDED = 5;
private int type;
private int modifierFlags;
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Wed Feb 08 19:22:20 2017 +0400
@@ -381,6 +381,13 @@
} else {
clickCount = [event clickCount];
}
+
+ jdouble deltaX = [event deltaX];
+ jdouble deltaY = [event deltaY];
+ if ([AWTToolkit hasPreciseScrollingDeltas: event]) {
+ deltaX = [event scrollingDeltaX] * 0.1;
+ deltaY = [event scrollingDeltaY] * 0.1;
+ }
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
@@ -391,8 +398,8 @@
[event buttonNumber],
(jint)localPoint.x, (jint)localPoint.y,
(jint)absP.x, (jint)absP.y,
- [event deltaY],
- [event deltaX],
+ deltaY,
+ deltaX,
[AWTToolkit scrollStateWithEvent: event]);
CHECK_NULL(jEvent);
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m Wed Feb 08 19:22:20 2017 +0400
@@ -139,7 +139,14 @@
jint clickCount;
clickCount = [event clickCount];
-
+
+ jdouble deltaX = [event deltaX];
+ jdouble deltaY = [event deltaY];
+ if ([AWTToolkit hasPreciseScrollingDeltas: event]) {
+ deltaX = [event scrollingDeltaX] * 0.1;
+ deltaY = [event scrollingDeltaY] * 0.1;
+ }
+
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -149,8 +156,8 @@
[event buttonNumber],
(jint)localPoint.x, (jint)localPoint.y,
(jint)absP.x, (jint)absP.y,
- [event deltaY],
- [event deltaX],
+ deltaY,
+ deltaX,
[AWTToolkit scrollStateWithEvent: event]);
CHECK_NULL(jEvent);
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h Wed Feb 08 19:22:20 2017 +0400
@@ -42,6 +42,7 @@
+ (long) getEventCount;
+ (void) eventCountPlusPlus;
+ (jint) scrollStateWithEvent: (NSEvent*) event;
++ (BOOL) hasPreciseScrollingDeltas: (NSEvent*) event;
@end
/*
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Wed Feb 08 19:22:20 2017 +0400
@@ -47,7 +47,7 @@
#define SCROLL_PHASE_UNSUPPORTED 1
#define SCROLL_PHASE_BEGAN 2
#define SCROLL_PHASE_CONTINUED 3
-#define SCROLL_PHASE_CANCELLED 4
+#define SCROLL_PHASE_MOMENTUM_BEGAN 4
#define SCROLL_PHASE_ENDED 5
int gNumberOfButtons;
@@ -85,16 +85,33 @@
return 0;
}
- NSEventPhase phase = [event phase];
- NSEventPhase momentumPhase = [event momentumPhase];
-
- if (!phase && !momentumPhase) return SCROLL_PHASE_UNSUPPORTED;
- switch (phase) {
- case NSEventPhaseBegan: return SCROLL_PHASE_BEGAN;
- case NSEventPhaseCancelled: return SCROLL_PHASE_CANCELLED;
- case NSEventPhaseEnded: return SCROLL_PHASE_ENDED;
- default: return SCROLL_PHASE_CONTINUED;
+ if ([event phase]) {
+ // process a phase of manual scrolling
+ switch ([event phase]) {
+ case NSEventPhaseBegan: return SCROLL_PHASE_BEGAN;
+ case NSEventPhaseCancelled: return SCROLL_PHASE_ENDED;
+ case NSEventPhaseEnded: return SCROLL_PHASE_ENDED;
+ default: return SCROLL_PHASE_CONTINUED;
+ }
}
+
+ if ([event momentumPhase]) {
+ // process a phase of automatic scrolling
+ switch ([event momentumPhase]) {
+ case NSEventPhaseBegan: return SCROLL_PHASE_MOMENTUM_BEGAN;
+ case NSEventPhaseCancelled: return SCROLL_PHASE_ENDED;
+ case NSEventPhaseEnded: return SCROLL_PHASE_ENDED;
+ default: return SCROLL_PHASE_CONTINUED;
+ }
+ }
+ // phase and momentum phase both are not set
+ return SCROLL_PHASE_UNSUPPORTED;
+}
+
++ (BOOL) hasPreciseScrollingDeltas: (NSEvent*) event {
+ return [event type] == NSScrollWheel
+ && [event respondsToSelector:@selector(hasPreciseScrollingDeltas)]
+ && [event hasPreciseScrollingDeltas];
}
@end
--- a/jdk/test/javax/swing/plaf/basic/BasicScrollPaneUI/8166591/TooMuchWheelRotationEventsTest.java Wed Feb 08 18:10:13 2017 +0300
+++ b/jdk/test/javax/swing/plaf/basic/BasicScrollPaneUI/8166591/TooMuchWheelRotationEventsTest.java Wed Feb 08 19:22:20 2017 +0400
@@ -40,7 +40,7 @@
/*
* @test
- * @bug 8166591
+ * @bug 8166591 8173876
* @key headful
* @summary [macos 10.12] Trackpad scrolling of text on OS X 10.12 Sierra
* is very fast (Trackpad, Retina only)