diff options
author | varunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-26 22:14:37 +0000 |
---|---|---|
committer | varunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-26 22:14:37 +0000 |
commit | 62531e1316efc119fd1342b367b8f6e7b6007c7a (patch) | |
tree | 0ff5d2ffcd7800172e241cfce7067716552dedfb | |
parent | a1ea5a9a54154af76ff112ccc363018aa8d985f7 (diff) | |
download | chromium_src-62531e1316efc119fd1342b367b8f6e7b6007c7a.zip chromium_src-62531e1316efc119fd1342b367b8f6e7b6007c7a.tar.gz chromium_src-62531e1316efc119fd1342b367b8f6e7b6007c7a.tar.bz2 |
GestureRecognizer: Long press should be cancelled on prevented-defaulted moves.
BUG=133375
TEST=added new test
Review URL: https://chromiumcodereview.appspot.com/10626009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144295 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/wm/system_gesture_event_filter.cc | 166 | ||||
-rw-r--r-- | ash/wm/system_gesture_event_filter.h | 50 | ||||
-rw-r--r-- | ash/wm/system_gesture_event_filter_unittest.cc | 81 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_recognizer_unittest.cc | 40 | ||||
-rw-r--r-- | ui/base/gestures/gesture_point.cc | 17 | ||||
-rw-r--r-- | ui/base/gestures/gesture_sequence.cc | 14 | ||||
-rw-r--r-- | ui/base/gestures/gesture_sequence.h | 2 | ||||
-rw-r--r-- | ui/base/gestures/gesture_util.cc | 23 | ||||
-rw-r--r-- | ui/base/gestures/gesture_util.h | 27 | ||||
-rw-r--r-- | ui/ui.gyp | 2 |
10 files changed, 322 insertions, 100 deletions
diff --git a/ash/wm/system_gesture_event_filter.cc b/ash/wm/system_gesture_event_filter.cc index 4af722d..2be1782 100644 --- a/ash/wm/system_gesture_event_filter.cc +++ b/ash/wm/system_gesture_event_filter.cc @@ -18,17 +18,14 @@ #include "ash/wm/window_util.h" #include "ash/wm/workspace/phantom_window_controller.h" #include "ash/wm/workspace/snap_sizer.h" -#include "base/timer.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkRect.h" #include "ui/aura/event.h" #include "ui/aura/root_window.h" -#include "ui/base/animation/animation.h" -#include "ui/base/animation/animation_delegate.h" -#include "ui/base/animation/linear_animation.h" #include "ui/base/gestures/gesture_configuration.h" +#include "ui/base/gestures/gesture_util.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/canvas.h" #include "ui/gfx/point.h" @@ -87,13 +84,19 @@ Widget* CreateAffordanceWidget() { return widget; } +} // namespace + +namespace ash { +namespace internal { + // View of the LongPressAffordanceAnimation. Draws the actual contents and // updates as the animation proceeds. It also maintains the views::Widget that // the animation is shown in. // Currently the affordance is to simply show an empty circle and fill it up as // the animation proceeds. // TODO(varunjain): Change the look of this affordance when we get official UX. -class LongPressAffordanceView : public views::View { +class LongPressAffordanceAnimation::LongPressAffordanceView + : public views::View { public: explicit LongPressAffordanceView(const gfx::Point& event_location) : views::View(), @@ -112,7 +115,6 @@ class LongPressAffordanceView : public views::View { } virtual ~LongPressAffordanceView() { - widget_->Hide(); } void UpdateWithAnimation(ui::Animation* animation) { @@ -148,100 +150,94 @@ class LongPressAffordanceView : public views::View { canvas->DrawPath(path, paint); } - scoped_ptr<Widget> widget_; + scoped_ptr<views::Widget> widget_; int current_angle_; DISALLOW_COPY_AND_ASSIGN(LongPressAffordanceView); }; -} // namespace - -namespace ash { -namespace internal { +LongPressAffordanceAnimation::LongPressAffordanceAnimation() + : ui::LinearAnimation(kAffordanceFrameRateHz, this), + view_(NULL), + tap_down_target_(NULL) { + int duration = + ui::GestureConfiguration::long_press_time_in_seconds() * 1000 - + ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000; + SetDuration(duration); +} -// LongPressAffordanceAnimation displays an animated affordance that is shown -// on a TAP_DOWN gesture. The animation completes on a LONG_PRESS gesture, or is -// canceled and hidden if any other event is received before that. -class SystemGestureEventFilter::LongPressAffordanceAnimation - : public ui::AnimationDelegate, - public ui::LinearAnimation { - public: - LongPressAffordanceAnimation() - : ui::LinearAnimation(kAffordanceFrameRateHz, this), - view_(NULL) { - int duration = - ui::GestureConfiguration::long_press_time_in_seconds() * 1000 - - ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000; - SetDuration(duration); - } +LongPressAffordanceAnimation::~LongPressAffordanceAnimation() {} - void ProcessEvent(aura::Window* target, aura::LocatedEvent* event) { - gfx::Point event_location; - int64 timer_start_time_ms = - ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000; - switch (event->type()) { - case ui::ET_GESTURE_TAP_DOWN: - // Start animation. - tap_down_location_ = event->root_location(); - timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(timer_start_time_ms), - this, - &LongPressAffordanceAnimation::StartAnimation); - break; - case ui::ET_TOUCH_MOVED: - // We do not want to stop the animation on every TOUCH_MOVED. Instead, - // we will rely on SCROLL_BEGIN to break the animation when the user - // moves their finger. - break; - case ui::ET_GESTURE_LONG_PRESS: - if (is_animating()) - End(); - // fall through to default to reset the view. - default: - // On all other touch and gesture events, we hide the animation. +void LongPressAffordanceAnimation::ProcessEvent(aura::Window* target, + aura::LocatedEvent* event) { + // Once we have a target, we are only interested in events on that target. + if (tap_down_target_ && tap_down_target_ != target) + return; + int64 timer_start_time_ms = + ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000; + switch (event->type()) { + case ui::ET_GESTURE_TAP_DOWN: + // Start animation. + tap_down_location_ = event->root_location(); + tap_down_target_ = target; + timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(timer_start_time_ms), + this, + &LongPressAffordanceAnimation::StartAnimation); + break; + case ui::ET_TOUCH_MOVED: + // If animation is running, We want it to be robust to small finger + // movements. So we stop the animation only when the finger moves a + // certain distance. + if (is_animating() && !ui::gestures::IsInsideManhattanSquare( + event->root_location(), tap_down_location_)) StopAnimation(); - break; - } - } - - private: - void StartAnimation() { - view_.reset(new LongPressAffordanceView(tap_down_location_)); - Start(); - } - - void StopAnimation() { - if (timer_.IsRunning()) - timer_.Stop(); - if (is_animating()) - Stop(); - view_.reset(); + break; + case ui::ET_GESTURE_LONG_PRESS: + if (is_animating()) + End(); + // fall through to default to reset the view and tap down target. + default: + // On all other touch and gesture events, we hide the animation. + StopAnimation(); + break; } +} - // Overridden from ui::LinearAnimation. - virtual void AnimateToState(double state) OVERRIDE { - DCHECK(view_.get()); - view_->UpdateWithAnimation(this); - } +void LongPressAffordanceAnimation::StartAnimation() { + view_.reset(new LongPressAffordanceView(tap_down_location_)); + Start(); +} - // Overridden from ui::AnimationDelegate. - virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE { - view_.reset(); - } +void LongPressAffordanceAnimation::StopAnimation() { + if (timer_.IsRunning()) + timer_.Stop(); + if (is_animating()) + Stop(); + view_.reset(); + tap_down_target_ = NULL; +} - virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE { - } +void LongPressAffordanceAnimation::AnimateToState(double state) { + DCHECK(view_.get()); + view_->UpdateWithAnimation(this); +} - virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE { - view_.reset(); - } +void LongPressAffordanceAnimation::AnimationEnded( + const ui::Animation* animation) { + view_.reset(); + tap_down_target_ = NULL; +} - scoped_ptr<LongPressAffordanceView> view_; - gfx::Point tap_down_location_; - base::OneShotTimer<LongPressAffordanceAnimation> timer_; +void LongPressAffordanceAnimation::AnimationProgressed( + const ui::Animation* animation) { +} - DISALLOW_COPY_AND_ASSIGN(LongPressAffordanceAnimation); -}; +void LongPressAffordanceAnimation::AnimationCanceled( + const ui::Animation* animation) { + view_.reset(); + tap_down_target_ = NULL; +} class SystemPinchHandler { public: diff --git a/ash/wm/system_gesture_event_filter.h b/ash/wm/system_gesture_event_filter.h index 3c258d7..9389c2f 100644 --- a/ash/wm/system_gesture_event_filter.h +++ b/ash/wm/system_gesture_event_filter.h @@ -8,18 +8,28 @@ #include "ash/shell.h" #include "ash/touch/touch_uma.h" +#include "base/timer.h" #include "ui/aura/event_filter.h" #include "ui/aura/window_observer.h" +#include "ui/base/animation/animation_delegate.h" +#include "ui/base/animation/linear_animation.h" +#include "ui/gfx/point.h" #include <map> namespace aura { -class MouseEvent; class KeyEvent; +class LocatedEvent; +class MouseEvent; class Window; } namespace ash { + +namespace test { +class SystemGestureEventFilterTest; +} // namespace test + namespace internal { class SystemPinchHandler; @@ -39,6 +49,41 @@ enum ScrollOrientation { SCROLL_ORIENTATION_VERTICAL }; +// LongPressAffordanceAnimation displays an animated affordance that is shown +// on a TAP_DOWN gesture. The animation completes on a LONG_PRESS gesture, or is +// canceled and hidden if any other event is received before that. +class LongPressAffordanceAnimation : public ui::AnimationDelegate, + public ui::LinearAnimation { + public: + LongPressAffordanceAnimation(); + virtual ~LongPressAffordanceAnimation(); + + // Display or removes long press affordance according to the |event|. + void ProcessEvent(aura::Window* target, aura::LocatedEvent* event); + + private: + friend class ash::test::SystemGestureEventFilterTest; + + void StartAnimation(); + void StopAnimation(); + + // Overridden from ui::LinearAnimation. + virtual void AnimateToState(double state) OVERRIDE; + + // Overridden from ui::AnimationDelegate. + virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE; + virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; + virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE; + + class LongPressAffordanceView; + scoped_ptr<LongPressAffordanceView> view_; + gfx::Point tap_down_location_; + aura::Window* tap_down_target_; + base::OneShotTimer<LongPressAffordanceAnimation> timer_; + + DISALLOW_COPY_AND_ASSIGN(LongPressAffordanceAnimation); +}; + // An event filter which handles system level gesture events. class SystemGestureEventFilter : public aura::EventFilter, public aura::WindowObserver { @@ -63,6 +108,8 @@ class SystemGestureEventFilter : public aura::EventFilter, virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; private: + friend class ash::test::SystemGestureEventFilterTest; + // Removes system-gesture handlers for a window. void ClearGestureHandlerForWindow(aura::Window* window); @@ -96,7 +143,6 @@ class SystemGestureEventFilter : public aura::EventFilter, // A device swipe gesture is in progress. bool is_scrubbing_; - class LongPressAffordanceAnimation; scoped_ptr<LongPressAffordanceAnimation> long_press_affordance_; TouchUMA touch_uma_; diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc index 2ca46bf..8f0fceb 100644 --- a/ash/wm/system_gesture_event_filter_unittest.cc +++ b/ash/wm/system_gesture_event_filter_unittest.cc @@ -4,6 +4,7 @@ #include "ash/wm/system_gesture_event_filter.h" +#include "base/timer.h" #include "ash/accelerators/accelerator_controller.h" #include "ash/launcher/launcher.h" #include "ash/launcher/launcher_model.h" @@ -95,7 +96,34 @@ class DummyBrightnessControlDelegate : public BrightnessControlDelegate, } // namespace -typedef test::AshTestBase SystemGestureEventFilterTest; +class SystemGestureEventFilterTest : public AshTestBase { + public: + SystemGestureEventFilterTest() : AshTestBase() {} + virtual ~SystemGestureEventFilterTest() {} + + internal::LongPressAffordanceAnimation* GetLongPressAffordance() { + Shell::TestApi shell_test(Shell::GetInstance()); + return shell_test.system_gesture_event_filter()-> + long_press_affordance_.get(); + } + + base::OneShotTimer<internal::LongPressAffordanceAnimation>* + GetLongPressAffordanceTimer() { + return &GetLongPressAffordance()->timer_; + } + + aura::Window* GetLongPressAffordanceTarget() { + return GetLongPressAffordance()->tap_down_target_; + } + + views::View* GetLongPressAffordanceView() { + return reinterpret_cast<views::View*>( + GetLongPressAffordance()->view_.get()); + } + + private: + DISALLOW_COPY_AND_ASSIGN(SystemGestureEventFilterTest); +}; // Ensure that events targeted at the root window are consumed by the // system event handler. @@ -341,5 +369,56 @@ TEST_F(SystemGestureEventFilterTest, ApplicationControl) { } } +TEST_F(SystemGestureEventFilterTest, LongPressAffordanceStateOnCaptureLoss) { + aura::RootWindow* root_window = Shell::GetPrimaryRootWindow(); + + aura::test::TestWindowDelegate delegate; + scoped_ptr<aura::Window> window0( + aura::test::CreateTestWindowWithDelegate( + &delegate, 9, gfx::Rect(0, 0, 100, 100), root_window)); + scoped_ptr<aura::Window> window1( + aura::test::CreateTestWindowWithDelegate( + &delegate, 10, gfx::Rect(0, 0, 100, 50), window0.get())); + scoped_ptr<aura::Window> window2( + aura::test::CreateTestWindowWithDelegate( + &delegate, 11, gfx::Rect(0, 50, 100, 50), window0.get())); + + const int kTouchId = 5; + + // Capture first window. + window1->SetCapture(); + EXPECT_TRUE(window1->HasCapture()); + + // Send touch event to first window. + aura::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId, + base::Time::NowFromSystemTime() - base::Time()); + root_window->DispatchTouchEvent(&press); + EXPECT_TRUE(window1->HasCapture()); + + base::OneShotTimer<internal::LongPressAffordanceAnimation>* timer = + GetLongPressAffordanceTimer(); + EXPECT_TRUE(timer->IsRunning()); + EXPECT_EQ(window1.get(), GetLongPressAffordanceTarget()); + + // Force timeout so that the affordance animation can start. + timer->user_task().Run(); + timer->Stop(); + EXPECT_TRUE(GetLongPressAffordance()->is_animating()); + + // Change capture. + window2->SetCapture(); + EXPECT_TRUE(window2->HasCapture()); + + EXPECT_TRUE(GetLongPressAffordance()->is_animating()); + EXPECT_EQ(window1.get(), GetLongPressAffordanceTarget()); + + // Animate to completion. + GetLongPressAffordance()->End(); + + // Check if state has reset. + EXPECT_EQ(NULL, GetLongPressAffordanceTarget()); + EXPECT_EQ(NULL, GetLongPressAffordanceView()); +} + } // namespace test } // namespace ash diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc index 8af48e5..e1344c3 100644 --- a/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -323,6 +323,10 @@ class TimerTestGestureSequence : public ui::GestureSequence { long_press_timer())->ForceTimeout(); } + bool IsTimerRunning() { + return long_press_timer()->IsRunning(); + } + base::OneShotTimer<ui::GestureSequence>* CreateTimer() { return new TestOneShotGestureSequenceTimer(); } @@ -2149,5 +2153,41 @@ TEST_F(GestureRecognizerTest, FlushAllOnHide) { root_window()->gesture_recognizer()->GetTouchLockedTarget(&press2)); } +TEST_F(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) { + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(root_window())); + const int kTouchId = 2; + gfx::Rect bounds(100, 200, 100, 100); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, NULL)); + delegate->set_window(window.get()); + + TimerTestGestureRecognizer* gesture_recognizer = + new TimerTestGestureRecognizer(root_window()); + TimerTestGestureSequence* gesture_sequence = + static_cast<TimerTestGestureSequence*>( + gesture_recognizer->GetGestureSequenceForTesting(window.get())); + + root_window()->SetGestureRecognizerForTesting(gesture_recognizer); + + delegate->Reset(); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), + kTouchId, GetTime()); + root_window()->DispatchTouchEvent(&press); + // Scroll around, to cancel the long press + SendScrollEvent(root_window(), 130, 230, kTouchId, delegate.get()); + + delegate->Reset(); + delegate->ReceivedAck(); + EXPECT_TRUE(delegate->tap_down()); + EXPECT_TRUE(gesture_sequence->IsTimerRunning()); + + delegate->Reset(); + delegate->ReceivedAckPreventDefaulted(); + EXPECT_FALSE(gesture_sequence->IsTimerRunning()); + gesture_sequence->ForceTimeout(); + EXPECT_FALSE(delegate->long_press()); +} + } // namespace test } // namespace aura diff --git a/ui/base/gestures/gesture_point.cc b/ui/base/gestures/gesture_point.cc index d75250a..77988ff 100644 --- a/ui/base/gestures/gesture_point.cc +++ b/ui/base/gestures/gesture_point.cc @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "ui/base/events.h" #include "ui/base/gestures/gesture_configuration.h" +#include "ui/base/gestures/gesture_util.h" #include "ui/base/gestures/gesture_types.h" namespace ui { @@ -147,22 +148,14 @@ bool GesturePoint::IsInSecondClickTimeWindow() const { } bool GesturePoint::IsInsideManhattanSquare(const TouchEvent& event) const { - int manhattanDistance = abs(event.GetLocation().x() - - first_touch_position_.x()) + - abs(event.GetLocation().y() - - first_touch_position_.y()); - return manhattanDistance < - GestureConfiguration::max_touch_move_in_pixels_for_click(); + return ui::gestures::IsInsideManhattanSquare(event.GetLocation(), + first_touch_position_); } bool GesturePoint::IsSecondClickInsideManhattanSquare( const TouchEvent& event) const { - int manhattanDistance = abs(event.GetLocation().x() - - last_tap_position_.x()) + - abs(event.GetLocation().y() - - last_tap_position_.y()); - return manhattanDistance < - GestureConfiguration::max_touch_move_in_pixels_for_click(); + return ui::gestures::IsInsideManhattanSquare(event.GetLocation(), + last_tap_position_); } bool GesturePoint::IsOverMinFlickSpeed() { diff --git a/ui/base/gestures/gesture_sequence.cc b/ui/base/gestures/gesture_sequence.cc index 3dd82d7..9892fdce 100644 --- a/ui/base/gestures/gesture_sequence.cc +++ b/ui/base/gestures/gesture_sequence.cc @@ -11,6 +11,7 @@ #include "base/time.h" #include "ui/base/events.h" #include "ui/base/gestures/gesture_configuration.h" +#include "ui/base/gestures/gesture_util.h" #include "ui/gfx/rect.h" namespace ui { @@ -219,6 +220,7 @@ GestureSequence::~GestureSequence() { GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( const TouchEvent& event, ui::TouchStatus status) { + StopLongPressTimerIfRequired(event); last_touch_location_ = event.GetLocation(); if (status != ui::TOUCH_STATUS_UNKNOWN) return NULL; // The event was consumed by a touch sequence. @@ -916,4 +918,16 @@ bool GestureSequence::MaybeSwipe(const TouchEvent& event, return true; } +void GestureSequence::StopLongPressTimerIfRequired(const TouchEvent& event) { + if (!long_press_timer_->IsRunning() || + event.GetEventType() != ui::ET_TOUCH_MOVED) + return; + + // Since long press timer has been started, there should be a non-NULL point. + const GesturePoint* point = GetPointByPointId(0); + if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(), + event.GetLocation())) + long_press_timer_->Stop(); +} + } // namespace ui diff --git a/ui/base/gestures/gesture_sequence.h b/ui/base/gestures/gesture_sequence.h index 78e9bb1..812e63e 100644 --- a/ui/base/gestures/gesture_sequence.h +++ b/ui/base/gestures/gesture_sequence.h @@ -165,6 +165,8 @@ class UI_EXPORT GestureSequence { const GesturePoint& point, Gestures* gestures); + void StopLongPressTimerIfRequired(const TouchEvent& event); + // Current state of gesture recognizer. GestureState state_; diff --git a/ui/base/gestures/gesture_util.cc b/ui/base/gestures/gesture_util.cc new file mode 100644 index 0000000..f4f003b --- /dev/null +++ b/ui/base/gestures/gesture_util.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/gestures/gesture_util.h" + +#include <stdlib.h> + +#include "ui/base/gestures/gesture_configuration.h" +#include "ui/gfx/point.h" + +namespace ui { +namespace gestures { + +bool IsInsideManhattanSquare(const gfx::Point& p1, + const gfx::Point& p2) { + int manhattan_distance = abs(p1.x() - p2.x()) + abs(p1.y() - p2.y()); + return manhattan_distance < + GestureConfiguration::max_touch_move_in_pixels_for_click(); +} + +} // namespace gestures +} // namespace ui diff --git a/ui/base/gestures/gesture_util.h b/ui/base/gestures/gesture_util.h new file mode 100644 index 0000000..9b49e85 --- /dev/null +++ b/ui/base/gestures/gesture_util.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_GESTURES_GESTURE_UTIL_H_ +#define UI_BASE_GESTURES_GESTURE_UTIL_H_ +#pragma once + +#include "ui/base/ui_export.h" + +namespace gfx { +class Point; +} // namespace gfx + +namespace ui { +namespace gestures { + +// Returns true if the distance between points |p1| and |p2| is less than a +// threshold. This is generally used to determine if a touch point has moved +// enough to be no longer considered a tap. +UI_EXPORT bool IsInsideManhattanSquare(const gfx::Point& p1, + const gfx::Point& p2); + +} // namespace gestures +} // namespace ui + +#endif // UI_BASE_GESTURES_GESTURE_UTIL_H_ @@ -147,6 +147,8 @@ 'base/gestures/gesture_sequence.h', 'base/gestures/gesture_types.cc', 'base/gestures/gesture_types.h', + 'base/gestures/gesture_util.cc', + 'base/gestures/gesture_util.h', 'base/gestures/velocity_calculator.cc', 'base/gestures/velocity_calculator.h', 'base/gtk/event_synthesis_gtk.cc', |