diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura/gestures/gesture_recognizer_unittest.cc | 51 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_sequence.h | 1 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 43 |
3 files changed, 74 insertions, 21 deletions
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc index 350806e..34e05ff 100644 --- a/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -274,7 +274,7 @@ class TimerTestGestureSequence : public GestureSequence { }; class TestGestureRecognizer : public GestureRecognizerAura { - public: + public: TestGestureRecognizer() : GestureRecognizerAura() { } @@ -282,6 +282,13 @@ class TestGestureRecognizer : public GestureRecognizerAura { GestureSequence* GetGestureSequenceForTesting(Window* window) { return GetGestureSequenceForWindow(window); } +}; + +class TimerTestGestureRecognizer : public TestGestureRecognizer { + public: + TimerTestGestureRecognizer() + : TestGestureRecognizer() { + } virtual GestureSequence* CreateSequence(RootWindow* root_window) OVERRIDE { return new TimerTestGestureSequence(root_window); @@ -563,8 +570,8 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) { delegate->Reset(); - TestGestureRecognizer* gesture_recognizer = - new TestGestureRecognizer(); + TimerTestGestureRecognizer* gesture_recognizer = + new TimerTestGestureRecognizer(); TimerTestGestureSequence* gesture_sequence = static_cast<TimerTestGestureSequence*>( gesture_recognizer->GetGestureSequenceForTesting(window.get())); @@ -604,8 +611,8 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { delegate->Reset(); - TestGestureRecognizer* gesture_recognizer = - new TestGestureRecognizer(); + TimerTestGestureRecognizer* gesture_recognizer = + new TimerTestGestureRecognizer(); TimerTestGestureSequence* gesture_sequence = static_cast<TimerTestGestureSequence*>( gesture_recognizer->GetGestureSequenceForTesting(window.get())); @@ -645,8 +652,8 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByPinch) { scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); - TestGestureRecognizer* gesture_recognizer = - new TestGestureRecognizer(); + TimerTestGestureRecognizer* gesture_recognizer = + new TimerTestGestureRecognizer(); TimerTestGestureSequence* gesture_sequence = static_cast<TimerTestGestureSequence*>( gesture_recognizer->GetGestureSequenceForTesting(window.get())); @@ -1419,6 +1426,36 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { EXPECT_EQ(windows[2], target); } +// Check that touch events outside the root window are still handled +// by the root window's gesture sequence. +TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { + TestGestureRecognizer* gesture_recognizer = + new TestGestureRecognizer(); + root_window()->SetGestureRecognizerForTesting(gesture_recognizer); + + scoped_ptr<aura::Window> window(CreateTestWindowWithBounds( + gfx::Rect(-100, -100, 2000, 2000), NULL)); + + GestureSequence* window_gesture_sequence = + gesture_recognizer->GetGestureSequenceForTesting(window.get()); + + GestureSequence* root_window_gesture_sequence = + gesture_recognizer->GetGestureSequenceForTesting(root_window()); + + gfx::Point pos1(-10, -10); + TouchEvent press1(ui::ET_TOUCH_PRESSED, pos1, 0); + root_window()->DispatchTouchEvent(&press1); + + gfx::Point pos2(1000, 1000); + TouchEvent press2(ui::ET_TOUCH_PRESSED, pos2, 1); + root_window()->DispatchTouchEvent(&press2); + + // As these presses were outside the root window, they should be + // associated with the root window. + EXPECT_EQ(0, window_gesture_sequence->point_count()); + EXPECT_EQ(2, root_window_gesture_sequence->point_count()); +} + TEST_F(GestureRecognizerTest, NoTapWithPreventDefaultedRelease) { scoped_ptr<QueueTouchEventDelegate> delegate( new QueueTouchEventDelegate(root_window())); diff --git a/ui/aura/gestures/gesture_sequence.h b/ui/aura/gestures/gesture_sequence.h index db82174..4f71934 100644 --- a/ui/aura/gestures/gesture_sequence.h +++ b/ui/aura/gestures/gesture_sequence.h @@ -44,6 +44,7 @@ class AURA_EXPORT GestureSequence { virtual Gestures* ProcessTouchEventForGesture(const TouchEvent& event, ui::TouchStatus status); const GesturePoint* points() const { return points_; } + int point_count() const { return point_count_; } // Maximum number of points in a single gesture. static const int kMaxGesturePoints = 12; diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 188c77c..1fd6a4a 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -266,21 +266,30 @@ bool RootWindow::DispatchTouchEvent(TouchEvent* event) { event->UpdateForRootTransform(layer()->transform()); bool handled = false; Window* target = capture_window_; - if (!target) - target = gesture_recognizer_->GetTargetForTouchEvent(event); - if (!target) - target = GetEventHandlerForPoint(event->location()); - if (!target) - return false; ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN; - TouchEvent translated_event(*event, this, target); - status = ProcessTouchEvent(target, &translated_event); - handled = status != ui::TOUCH_STATUS_UNKNOWN; - if (status == ui::TOUCH_STATUS_QUEUED || - status == ui::TOUCH_STATUS_QUEUED_END) - gesture_recognizer_->QueueTouchEventForGesture(target, *event); + if (!target) + target = gesture_recognizer_->GetTargetForTouchEvent(event); + + if (!target && !bounds().Contains(event->location())) { + // If the touch is outside the root window, set its target to the + // root window. + target = this; + } else { + if (!target) + target = GetEventHandlerForPoint(event->location()); + if (!target) + return false; + + TouchEvent translated_event(*event, this, target); + status = ProcessTouchEvent(target, &translated_event); + handled = status != ui::TOUCH_STATUS_UNKNOWN; + + if (status == ui::TOUCH_STATUS_QUEUED || + status == ui::TOUCH_STATUS_QUEUED_END) + gesture_recognizer_->QueueTouchEventForGesture(target, *event); + } // Get the list of GestureEvents from GestureRecognizer. scoped_ptr<GestureRecognizer::Gestures> gestures; @@ -560,6 +569,8 @@ bool RootWindow::ProcessMouseEvent(Window* target, MouseEvent* event) { return true; } + if (!target->delegate()) + return false; return target->delegate()->OnMouseEvent(event); } @@ -613,7 +624,10 @@ ui::GestureStatus RootWindow::ProcessGestureEvent(Window* target, return ui::GESTURE_STATUS_UNKNOWN; EventFilters filters; - GetEventFiltersToNotify(target->parent(), &filters); + if (target == this) + GetEventFiltersToNotify(target, &filters); + else + GetEventFiltersToNotify(target->parent(), &filters); ui::GestureStatus status = ui::GESTURE_STATUS_UNKNOWN; for (EventFilters::const_reverse_iterator it = filters.rbegin(), rend = filters.rend(); @@ -623,7 +637,8 @@ ui::GestureStatus RootWindow::ProcessGestureEvent(Window* target, return status; } - status = target->delegate()->OnGestureEvent(event); + if (target->delegate()) + status = target->delegate()->OnGestureEvent(event); if (status == ui::GESTURE_STATUS_UNKNOWN) { // The gesture was unprocessed. Generate corresponding mouse events here // (e.g. tap to click). |