提交 97d1be10 编写于 作者: M malenkov

8173876: Fast precise scrolling and DeltaAccumulator fix for macOS Sierra 10.12.2

Reviewed-by: serb, alexsch
上级 ad8c22f1
...@@ -262,9 +262,8 @@ final class CPlatformResponder { ...@@ -262,9 +262,8 @@ final class CPlatformResponder {
static class DeltaAccumulator { static class DeltaAccumulator {
static final double MIN_THRESHOLD = 0.1;
static final double MAX_THRESHOLD = 0.5;
double accumulatedDelta; double accumulatedDelta;
boolean accumulate;
int getRoundedDelta(double delta, int scrollPhase) { int getRoundedDelta(double delta, int scrollPhase) {
...@@ -275,25 +274,23 @@ final class CPlatformResponder { ...@@ -275,25 +274,23 @@ final class CPlatformResponder {
roundDelta = delta > 0 ? 1 : -1; roundDelta = delta > 0 ? 1 : -1;
} }
} else { // trackpad } else { // trackpad
boolean begin = scrollPhase == NSEvent.SCROLL_PHASE_BEGAN; if (scrollPhase == NSEvent.SCROLL_PHASE_BEGAN) {
boolean end = scrollPhase == NSEvent.SCROLL_MASK_PHASE_ENDED
|| scrollPhase == NSEvent.SCROLL_MASK_PHASE_CANCELLED;
if (begin) {
accumulatedDelta = 0; accumulatedDelta = 0;
accumulate = true;
}
else if (scrollPhase == NSEvent.SCROLL_PHASE_MOMENTUM_BEGAN) {
accumulate = true;
} }
if (accumulate) {
accumulatedDelta += delta; accumulatedDelta += delta;
double absAccumulatedDelta = Math.abs(accumulatedDelta);
if (absAccumulatedDelta > MAX_THRESHOLD) {
roundDelta = (int) Math.round(accumulatedDelta); roundDelta = (int) Math.round(accumulatedDelta);
accumulatedDelta -= roundDelta; accumulatedDelta -= roundDelta;
}
if (end) { if (scrollPhase == NSEvent.SCROLL_PHASE_ENDED) {
if (roundDelta == 0 && absAccumulatedDelta > MIN_THRESHOLD) { accumulate = false;
roundDelta = accumulatedDelta > 0 ? 1 : -1;
} }
} }
} }
......
...@@ -36,8 +36,8 @@ final class NSEvent { ...@@ -36,8 +36,8 @@ final class NSEvent {
static final int SCROLL_PHASE_UNSUPPORTED = 1; static final int SCROLL_PHASE_UNSUPPORTED = 1;
static final int SCROLL_PHASE_BEGAN = 2; static final int SCROLL_PHASE_BEGAN = 2;
static final int SCROLL_PHASE_CONTINUED = 3; static final int SCROLL_PHASE_CONTINUED = 3;
static final int SCROLL_MASK_PHASE_CANCELLED = 4; static final int SCROLL_PHASE_MOMENTUM_BEGAN = 4;
static final int SCROLL_MASK_PHASE_ENDED = 5; static final int SCROLL_PHASE_ENDED = 5;
private int type; private int type;
private int modifierFlags; private int modifierFlags;
......
...@@ -385,6 +385,13 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -385,6 +385,13 @@ AWT_ASSERT_APPKIT_THREAD;
clickCount = [event 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_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V"); static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent, jobject jEvent = JNFNewObject(env, jctor_NSEvent,
...@@ -394,8 +401,8 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -394,8 +401,8 @@ AWT_ASSERT_APPKIT_THREAD;
[event buttonNumber], [event buttonNumber],
(jint)localPoint.x, (jint)localPoint.y, (jint)localPoint.x, (jint)localPoint.y,
(jint)absP.x, (jint)absP.y, (jint)absP.x, (jint)absP.y,
[event deltaY], deltaY,
[event deltaX], deltaX,
[AWTToolkit scrollStateWithEvent: event]); [AWTToolkit scrollStateWithEvent: event]);
if (jEvent == nil) { if (jEvent == nil) {
// Unable to create event by some reason. // Unable to create event by some reason.
......
...@@ -135,6 +135,13 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) { ...@@ -135,6 +135,13 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) {
clickCount = [event 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_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V"); static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent, jobject jEvent = JNFNewObject(env, jctor_NSEvent,
...@@ -144,8 +151,8 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) { ...@@ -144,8 +151,8 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) {
[event buttonNumber], [event buttonNumber],
(jint)localPoint.x, (jint)localPoint.y, (jint)localPoint.x, (jint)localPoint.y,
(jint)absP.x, (jint)absP.y, (jint)absP.x, (jint)absP.y,
[event deltaY], deltaY,
[event deltaX], deltaX,
[AWTToolkit scrollStateWithEvent: event]); [AWTToolkit scrollStateWithEvent: event]);
if (jEvent == nil) { if (jEvent == nil) {
// Unable to create event by some reason. // Unable to create event by some reason.
......
...@@ -41,6 +41,7 @@ extern jint* gButtonDownMasks; ...@@ -41,6 +41,7 @@ extern jint* gButtonDownMasks;
+ (long) getEventCount; + (long) getEventCount;
+ (void) eventCountPlusPlus; + (void) eventCountPlusPlus;
+ (jint) scrollStateWithEvent: (NSEvent*) event; + (jint) scrollStateWithEvent: (NSEvent*) event;
+ (BOOL) hasPreciseScrollingDeltas: (NSEvent*) event;
@end @end
/* /*
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#define SCROLL_PHASE_UNSUPPORTED 1 #define SCROLL_PHASE_UNSUPPORTED 1
#define SCROLL_PHASE_BEGAN 2 #define SCROLL_PHASE_BEGAN 2
#define SCROLL_PHASE_CONTINUED 3 #define SCROLL_PHASE_CONTINUED 3
#define SCROLL_PHASE_CANCELLED 4 #define SCROLL_PHASE_MOMENTUM_BEGAN 4
#define SCROLL_PHASE_ENDED 5 #define SCROLL_PHASE_ENDED 5
int gNumberOfButtons; int gNumberOfButtons;
...@@ -67,16 +67,33 @@ static long eventCount; ...@@ -67,16 +67,33 @@ static long eventCount;
return 0; return 0;
} }
NSEventPhase phase = [event phase]; if ([event phase]) {
NSEventPhase momentumPhase = [event momentumPhase]; // process a phase of manual scrolling
switch ([event phase]) {
if (!phase && !momentumPhase) return SCROLL_PHASE_UNSUPPORTED;
switch (phase) {
case NSEventPhaseBegan: return SCROLL_PHASE_BEGAN; case NSEventPhaseBegan: return SCROLL_PHASE_BEGAN;
case NSEventPhaseCancelled: return SCROLL_PHASE_CANCELLED; 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; case NSEventPhaseEnded: return SCROLL_PHASE_ENDED;
default: return SCROLL_PHASE_CONTINUED;
}
} }
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 @end
......
...@@ -40,7 +40,7 @@ import javax.swing.SwingUtilities; ...@@ -40,7 +40,7 @@ import javax.swing.SwingUtilities;
/* /*
* @test * @test
* @bug 8166591 * @bug 8166591 8173876
* @summary [macos 10.12] Trackpad scrolling of text on OS X 10.12 Sierra * @summary [macos 10.12] Trackpad scrolling of text on OS X 10.12 Sierra
* is very fast (Trackpad, Retina only) * is very fast (Trackpad, Retina only)
* @run main/manual/othervm TooMuchWheelRotationEventsTest * @run main/manual/othervm TooMuchWheelRotationEventsTest
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册