summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-14 17:06:52 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-14 17:06:52 +0000
commitc2996a9124fa16f8b827ce370a840c2b3656e736 (patch)
tree50d4e0048a6d86eac786c5cc847b3bc68f21dc58
parent9598dce7a441e64828958482b4f9fa23d95c674e (diff)
downloadchromium_src-c2996a9124fa16f8b827ce370a840c2b3656e736.zip
chromium_src-c2996a9124fa16f8b827ce370a840c2b3656e736.tar.gz
chromium_src-c2996a9124fa16f8b827ce370a840c2b3656e736.tar.bz2
touch: Fix touch events bubbling up the hierarchy.
BUG=none TEST=none Review URL: http://codereview.chromium.org/6690003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78045 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--views/view_unittest.cc21
-rw-r--r--views/widget/root_view.cc28
2 files changed, 34 insertions, 15 deletions
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 76eb1c9..c799afd 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -217,6 +217,16 @@ class MockGestureManager : public GestureManager {
DISALLOW_COPY_AND_ASSIGN(MockGestureManager);
};
+// A view subclass that ignores all touch events for testing purposes.
+class TestViewIgnoreTouch : public TestView {
+ public:
+ TestViewIgnoreTouch() : TestView() {
+ }
+
+ virtual ~TestViewIgnoreTouch() {}
+ private:
+ virtual TouchStatus OnTouchEvent(const TouchEvent& event);
+};
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -450,6 +460,10 @@ View::TouchStatus TestView::OnTouchEvent(const TouchEvent& event) {
TOUCH_STATUS_UNKNOWN;
}
+View::TouchStatus TestViewIgnoreTouch::OnTouchEvent(const TouchEvent& event) {
+ return TOUCH_STATUS_UNKNOWN;
+}
+
TEST_F(ViewTest, TouchEvent) {
MockGestureManager* gm = new MockGestureManager();
@@ -459,6 +473,9 @@ TEST_F(ViewTest, TouchEvent) {
TestView* v2 = new TestView();
v2->SetBounds(100, 100, 100, 100);
+ TestView* v3 = new TestViewIgnoreTouch();
+ v3->SetBounds(0, 0, 100, 100);
+
scoped_ptr<Widget> window(CreateWidget());
#if defined(OS_WIN)
// This code would need to be here when we support
@@ -473,6 +490,10 @@ TEST_F(ViewTest, TouchEvent) {
root->AddChildView(v1);
root->SetGestureManager(gm);
v1->AddChildView(v2);
+ v2->AddChildView(v3);
+
+ // |v3| completely obscures |v2|, but all the touch events on |v3| should
+ // reach |v2| because |v3| doesn't process any touch events.
// Make sure if none of the views handle the touch event, the gesture manager
// does.
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index 484ceba..32805df 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -369,27 +369,25 @@ View::TouchStatus RootView::OnTouchEvent(const TouchEvent& event) {
TouchEvent touch_event(e, this, touch_pressed_handler_);
status = touch_pressed_handler_->ProcessTouchEvent(touch_event);
- // If the touch didn't initiate a touch-sequence, then reset the touch event
- // handler.
- if (status != TOUCH_STATUS_START)
- touch_pressed_handler_ = NULL;
-
// The view could have removed itself from the tree when handling
// OnTouchEvent(). So handle as per OnMousePressed. NB: we
// assume that the RootView itself cannot be so removed.
- //
- // NOTE: Don't return true here, because we don't want the frame to
- // forward future events to us when there's no handler.
if (!touch_pressed_handler_)
break;
- // If the view handled the event, leave touch_pressed_handler_ set and
- // return true, which will cause subsequent drag/release events to get
- // forwarded to that view.
- if (status != TOUCH_STATUS_UNKNOWN) {
- gesture_manager_->ProcessTouchEventForGesture(e, this, status);
- return status;
- }
+ // The touch event wasn't processed. Go up the view hierarchy and dispatch
+ // the touch event.
+ if (status == TOUCH_STATUS_UNKNOWN)
+ continue;
+
+ // If the touch didn't initiate a touch-sequence, then reset the touch event
+ // handler. Otherwise, leave it set so that subsequent touch events are
+ // dispatched to the same handler.
+ if (status != TOUCH_STATUS_START)
+ touch_pressed_handler_ = NULL;
+
+ gesture_manager_->ProcessTouchEventForGesture(e, this, status);
+ return status;
}
// Reset touch_pressed_handler_ to indicate that no processing is occurring.