diff options
author | erikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-22 18:06:09 +0000 |
---|---|---|
committer | erikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-22 18:06:09 +0000 |
commit | 5717d08549643f43cab600a71e68adf8193e06f6 (patch) | |
tree | e6e24c72110818f6d47252417d83a11daa698975 | |
parent | afb646955341d09ca15326175b0e8ab6abfbb628 (diff) | |
download | chromium_src-5717d08549643f43cab600a71e68adf8193e06f6.zip chromium_src-5717d08549643f43cab600a71e68adf8193e06f6.tar.gz chromium_src-5717d08549643f43cab600a71e68adf8193e06f6.tar.bz2 |
Merge 241918 "mac: Fix a newly introduced history swiping bug."
> mac: Fix a newly introduced history swiping bug.
>
> Attempting to 2-finger history swipe twice in quick succession would
> fail to register the second swipe ~50% of the time. The NSEvent callback with
> phase=NSEventPhaseBegan non-deterministically occurs before the event has been
> registered as a gesture. This was causing the history_swiper to process the
> event as part of the previous gesture.
>
> BUG=138175
> TEST=In a single tab, navigate to 5 different sites. Use a trackpad to 2-finger
> swipe repeatedly in the same direction. Each swipe should register as a history
> swipe, and cause the page to navigate in the appropriate direction. There
> should be no jankiness, and the touches should not fail to register.
>
> Review URL: https://codereview.chromium.org/117733002
TBR=erikchen@chromium.org
Review URL: https://codereview.chromium.org/132693021
git-svn-id: svn://svn.chromium.org/chrome/branches/1750/src@246367 0039d316-1c4b-4281-b951-d872f2087c98
3 files changed, 34 insertions, 0 deletions
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h index c2383f8..bbaf962 100644 --- a/base/mac/sdk_forward_declarations.h +++ b/base/mac/sdk_forward_declarations.h @@ -22,6 +22,7 @@ enum { NSEventPhaseChanged = 0x1 << 2, NSEventPhaseEnded = 0x1 << 3, NSEventPhaseCancelled = 0x1 << 4, + NSEventPhaseMayBegin = 0x1 << 5 }; typedef NSUInteger NSEventPhase; diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm index 08c758e..d96a154 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm @@ -282,9 +282,18 @@ - (BOOL)maybeHandleHistorySwiping:(NSEvent*)theEvent { // We've already processed this gesture. if (lastProcessedGestureId_ == currentGestureId_) { + // A new event may come in before it's recognized as a gesture. + // We have not yet reset the state from the last gesture. + // Let it pass through. + if ([theEvent phase] == NSEventPhaseBegan || + [theEvent phase] == NSEventPhaseMayBegin) { + return NO; + } + // The user cancelled the history swiper. Ignore all events. if (historySwipeCancelled_) return NO; + // The user completed the history swiper. Swallow all events. return YES; } diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm index bd2d382..2e0c3ba 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm @@ -328,3 +328,27 @@ TEST_F(MacHistorySwiperTest, NoSwipe) { EXPECT_EQ(begin_count_, 0); EXPECT_EQ(end_count_, 0); } + +// After a gesture is successfully recognized, momentum events should be +// swallowed, but new events should pass through. +TEST_F(MacHistorySwiperTest, TouchEventAfterGestureFinishes) { + // These tests require 10.7+ APIs. + if (![NSEvent + respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) + return; + + // Successfully pass through a gesture. + startGestureInMiddle(); + moveGestureInMiddle(); + moveGestureAtPoint(makePoint(0.8, 0.5)); + endGestureAtPoint(makePoint(0.8, 0.5)); + EXPECT_TRUE(navigated_right_); + + // Momentum events should be swallowed. + NSEvent* momentumEvent = scrollWheelEventWithPhase(NSEventPhaseNone); + EXPECT_TRUE([historySwiper_ handleEvent:momentumEvent]); + + // New events should not be swallowed. + NSEvent* beganEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); + EXPECT_FALSE([historySwiper_ handleEvent:beganEvent]); +} |