Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Unified Diff: ui/views/widget/widget_unittest.cc

Issue 404213003: [WIP] Allow scroll events to permanently change the default gesture handler in RootView (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: friend test Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/views/widget/widget_unittest.cc
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index a4ac6e4a42c0aa876812191ab9cbb83a483f078e..a2ae25c94b252dd0e8e5f31d0437ae608565c4ff 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -1399,26 +1399,8 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
widget->SetBounds(gfx::Rect(0, 0, 100, 100));
widget->Show();
- ui::GestureEvent begin(5,
- 5,
- 0,
- ui::EventTimeForNow(),
- ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0));
- ui::GestureEvent end(5,
- 5,
- 0,
- ui::EventTimeForNow(),
- ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0));
- widget->OnGestureEvent(&begin);
- EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_BEGIN));
- EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_BEGIN));
- EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_BEGIN));
-
- widget->OnGestureEvent(&end);
- EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_END));
- EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_END));
-
+ // Dispatch a ui::ET_SCROLL event. The event remains unhandled and should
+ // bubble up the views hierarchy to be re-dispatched on the root view.
ui::ScrollEvent scroll(ui::ET_SCROLL,
gfx::Point(5, 5),
ui::EventTimeForNow(),
@@ -1440,6 +1422,8 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
view->ResetCounts();
h2.ResetCounts();
+ // Dispatch a ui::ET_SCROLL_FLING_START event. The event remains unhandled and
+ // should bubble up the views hierarchy to be re-dispatched on the root view.
ui::ScrollEvent fling(ui::ET_SCROLL_FLING_START,
gfx::Point(5, 5),
ui::EventTimeForNow(),
@@ -1462,13 +1446,43 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
view->ResetCounts();
h2.ResetCounts();
- // Replace the child of |root_view| with a ScrollableEventCountView so that
- // ui::ET_SCROLL events are marked as handled at the target phase.
- root_view->RemoveChildView(view.get());
- ScrollableEventCountView* scroll_view = new ScrollableEventCountView;
- scroll_view->SetBounds(0, 0, 20, 20);
- root_view->AddChildView(scroll_view);
+ // Change the handle mode of |view| so that events are marked as handled at
+ // the target phase.
+ view->set_handle_mode(EventCountView::CONSUME_EVENTS);
+ // Dispatch a ui::ET_GESTURE_TAP_DOWN and a ui::ET_GESTURE_TAP_CANCEL event.
+ // The events are handled at the target phase and should not reach the
+ // post-target handler.
+ ui::GestureEvent tap_down(5,
+ 5,
+ 0,
+ ui::EventTimeForNow(),
+ ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN,
+ 0,
+ 0));
+ widget->OnGestureEvent(&tap_down);
+ EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+ EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+ EXPECT_EQ(0, h2.GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+
+ ui::GestureEvent tap_cancel(5,
+ 5,
+ 0,
+ ui::EventTimeForNow(),
+ ui::GestureEventDetails(ui::ET_GESTURE_TAP_CANCEL,
+ 0,
+ 0));
+ widget->OnGestureEvent(&tap_cancel);
+ EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+ EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+ EXPECT_EQ(0, h2.GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+
+ h1.ResetCounts();
+ view->ResetCounts();
+ h2.ResetCounts();
+
+ // Dispatch a ui::ET_SCROLL event. The event is handled at the target phase
+ // and should not reach the post-target handler.
ui::ScrollEvent consumed_scroll(ui::ET_SCROLL,
gfx::Point(5, 5),
ui::EventTimeForNow(),
@@ -1477,16 +1491,13 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
0, 20,
2);
widget->OnScrollEvent(&consumed_scroll);
-
- // The event is handled at the target phase and should not reach the
- // post-target handler.
EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
- EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_SCROLL));
+ EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
EXPECT_EQ(0, h2.GetEventCount(ui::ET_SCROLL));
// Handled scroll events are not turned into wheel events and re-dispatched.
EXPECT_EQ(0, h1.GetEventCount(ui::ET_MOUSEWHEEL));
- EXPECT_EQ(0, scroll_view->GetEventCount(ui::ET_MOUSEWHEEL));
+ EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSEWHEEL));
EXPECT_EQ(0, h2.GetEventCount(ui::ET_MOUSEWHEEL));
widget->CloseNow();
@@ -1957,8 +1968,11 @@ class GestureEventForTest : public ui::GestureEvent {
// Tests that the |gesture_handler_| member in RootView is always NULL
// after the dispatch of a ui::ET_GESTURE_END event corresponding to
-// the release of the final touch point on the screen.
-TEST_F(WidgetTest, GestureHandlerNotSetOnGestureEnd) {
+// the release of the final touch point on the screen and that
+// ui::ET_GESTURE_END events are never dispatched to a view. Also
+// verifies that ui::ET_GESTURE_BEGIN is never dispatched to a view
+// and does not change the value of |gesture_handler_|.
+TEST_F(WidgetTest, GestureBeginAndEndEvents) {
Widget* widget = CreateTopLevelNativeWidget();
widget->SetBounds(gfx::Rect(0, 0, 300, 300));
EventCountView* view = new EventCountView();
@@ -1968,42 +1982,76 @@ TEST_F(WidgetTest, GestureHandlerNotSetOnGestureEnd) {
root_view->AddChildView(view);
widget->Show();
- // If no gesture handler is set, dispatching only a ui::ET_GESTURE_END
- // event should not set the gesture handler if the event remains unhandled.
+ // If no gesture handler is set, dispatching a ui::ET_GESTURE_END or
+ // ui::ET_GESTURE_BEGIN event should not set the gesture handler and
+ // the events should remain unhandled.
EXPECT_EQ(NULL, GetGestureHandler(root_view));
GestureEventForTest end(ui::ET_GESTURE_END, 15, 15);
widget->OnGestureEvent(&end);
EXPECT_FALSE(end.handled());
EXPECT_EQ(NULL, GetGestureHandler(root_view));
- // If no gesture handler is set, dispatching only a ui::ET_GESTURE_END
- // event should not set the gesture handler event if the event is handled.
+ GestureEventForTest begin(ui::ET_GESTURE_BEGIN, 15, 15);
+ widget->OnGestureEvent(&begin);
+ EXPECT_FALSE(begin.handled());
+ EXPECT_EQ(NULL, GetGestureHandler(root_view));
+
+ // Change the handle mode of |view| to indicate that it would like
+ // to handle all events.
view->set_handle_mode(EventCountView::CONSUME_EVENTS);
+
+ // If no gesture handler is set, dispatching only a ui::ET_GESTURE_END
+ // or ui::ET_GESTURE_BEGIN event should not set the gesture handler.
+ // Furthermore, because these events are never dispatched to any view,
+ // the events should remain unhandled even if the view has indicated
+ // that they wish to handle these events.
end = GestureEventForTest(ui::ET_GESTURE_END, 15, 15);
widget->OnGestureEvent(&end);
- EXPECT_TRUE(end.handled());
+ EXPECT_FALSE(end.handled());
+ EXPECT_EQ(NULL, GetGestureHandler(root_view));
+
+ begin = GestureEventForTest(ui::ET_GESTURE_BEGIN, 15, 15);
+ widget->OnGestureEvent(&begin);
+ EXPECT_FALSE(begin.handled());
EXPECT_EQ(NULL, GetGestureHandler(root_view));
// If the gesture handler has been set by a previous gesture, then
- // it should be reset to NULL by a ui::ET_GESTURE_END.
+ // it should remain unchanged on a ui::ET_GESTURE_BEGIN and be reset
+ // to NULL by a ui::ET_GESTURE_END.
GestureEventForTest tap(ui::ET_GESTURE_TAP, 15, 15);
widget->OnGestureEvent(&tap);
EXPECT_TRUE(tap.handled());
EXPECT_EQ(view, GetGestureHandler(root_view));
+
+ begin = GestureEventForTest(ui::ET_GESTURE_BEGIN, 15, 15);
+ widget->OnGestureEvent(&begin);
+ EXPECT_FALSE(begin.handled());
+ EXPECT_EQ(view, GetGestureHandler(root_view));
+
end = GestureEventForTest(ui::ET_GESTURE_END, 15, 15);
widget->OnGestureEvent(&end);
- EXPECT_TRUE(end.handled());
+ EXPECT_FALSE(end.handled());
EXPECT_EQ(NULL, GetGestureHandler(root_view));
// If the gesture handler has been set by a previous gesture, then
- // it should be reset to NULL by a ui::ET_GESTURE_END, even when
- // the gesture handler does not actually handle the end event.
+ // it should remain unchanged on a ui::ET_GESTURE_BEGIN and be reset
+ // to NULL by a ui::ET_GESTURE_END, even when the gesture handler has
+ // indicated that it would not like to handle any further events.
tap = GestureEventForTest(ui::ET_GESTURE_TAP, 15, 15);
widget->OnGestureEvent(&tap);
EXPECT_TRUE(tap.handled());
EXPECT_EQ(view, GetGestureHandler(root_view));
- end = GestureEventForTest(ui::ET_GESTURE_END, 15, 15);
+
+ // Change the handle mode of |view| to indicate that it does not want
+ // to handle any further events.
view->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
+
+ begin = GestureEventForTest(ui::ET_GESTURE_BEGIN, 15, 15);
+ widget->OnGestureEvent(&begin);
+ EXPECT_FALSE(begin.handled());
+ EXPECT_EQ(view, GetGestureHandler(root_view));
+
+ end = GestureEventForTest(ui::ET_GESTURE_END, 15, 15);
widget->OnGestureEvent(&end);
EXPECT_FALSE(end.handled());
EXPECT_EQ(NULL, GetGestureHandler(root_view));
@@ -2014,7 +2062,6 @@ TEST_F(WidgetTest, GestureHandlerNotSetOnGestureEnd) {
// Tests that a (non-scroll) gesture event is dispatched to the correct views
// in a view hierarchy and that the default gesture handler in RootView is set
// correctly.
-// TODO(tdanderson): Create a test similar to ViewTest.ScrollGestureEvent.
TEST_F(WidgetTest, GestureEventDispatch) {
Widget* widget = CreateTopLevelNativeWidget();
widget->SetBounds(gfx::Rect(0, 0, 300, 300));
@@ -2124,6 +2171,153 @@ TEST_F(WidgetTest, GestureEventDispatch) {
widget->Close();
}
+// Tests that scroll events will change the default gesture handler in
+// RootView if the current handler to which they are dispatched does not
+// handle scroll events.
+TEST_F(WidgetTest, ScrollGestureEventDispatch) {
+ Widget* widget = CreateTopLevelNativeWidget();
+ widget->SetBounds(gfx::Rect(0, 0, 300, 300));
+
+ // Define a hierarchy of four views (coordinates are in
+ // their parent coordinate space).
+ // v1 (0, 0, 300, 300)
+ // v2 (0, 0, 100, 100)
+ // v3 (0, 0, 50, 50)
+ // v4(0, 0, 10, 10)
+ EventCountView* v1 = new EventCountView();
+ v1->SetBounds(0, 0, 300, 300);
+ EventCountView* v2 = new EventCountView();
+ v2->SetBounds(0, 0, 100, 100);
+ EventCountView* v3 = new EventCountView();
+ v3->SetBounds(0, 0, 50, 50);
+ EventCountView* v4 = new EventCountView();
+ v4->SetBounds(0, 0, 10, 10);
+ internal::RootView* root_view =
+ static_cast<internal::RootView*>(widget->GetRootView());
+ root_view->AddChildView(v1);
+ v1->AddChildView(v2);
+ v2->AddChildView(v3);
+ v3->AddChildView(v4);
+
+ widget->Show();
+
+ // Change the handle mode of |v3| to indicate that it would like to handle
+ // gesture events.
+ v3->set_handle_mode(EventCountView::CONSUME_EVENTS);
+
+ // When no gesture handler is set, dispatching a ui::ET_GESTURE_TAP_DOWN
+ // should bubble up the views hierarchy until it reaches the first view
+ // that will handle it (|v3|) and then sets the handler to |v3|.
+ EXPECT_EQ(NULL, GetGestureHandler(root_view));
+ GestureEventForTest tap_down(ui::ET_GESTURE_TAP_DOWN, 5, 5);
+ widget->OnGestureEvent(&tap_down);
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+ EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+ EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
+ EXPECT_EQ(v3, GetGestureHandler(root_view));
+ EXPECT_TRUE(tap_down.handled());
+ v1->ResetCounts();
+ v2->ResetCounts();
+ v3->ResetCounts();
+ v4->ResetCounts();
+
+ // A ui::ET_GESTURE_TAP_CANCEL event should be dispatched to |v3| directly.
+ GestureEventForTest tap_cancel(ui::ET_GESTURE_TAP_CANCEL, 5, 5);
+ widget->OnGestureEvent(&tap_cancel);
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+ EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
+ EXPECT_EQ(v3, GetGestureHandler(root_view));
+ EXPECT_TRUE(tap_cancel.handled());
+ v1->ResetCounts();
+ v2->ResetCounts();
+ v3->ResetCounts();
+ v4->ResetCounts();
+
+ // Change the handle mode of |v3| to indicate that it would no longer like
+ // to handle events, and change the mode of |v1| to indicate that it would
+ // like to handle events.
+ v3->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
+ v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
+
+ // Dispatch a ui::ET_GESTURE_SCROLL_BEGIN event. Because the current gesture
+ // handler (|v3|) does not handle scroll events, the event should bubble up
+ // the views hierarchy until it reaches the first view that will handle
+ // it (|v1|) and then sets the handler to |v1|.
+ GestureEventForTest scroll_begin(ui::ET_GESTURE_SCROLL_BEGIN, 5, 5);
+ widget->OnGestureEvent(&scroll_begin);
+ EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
+ EXPECT_EQ(1, v2->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
+ EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
+ EXPECT_EQ(v1, GetGestureHandler(root_view));
+ EXPECT_TRUE(scroll_begin.handled());
+ v1->ResetCounts();
+ v2->ResetCounts();
+ v3->ResetCounts();
+ v4->ResetCounts();
+
+ // A ui::ET_GESTURE_SCROLL_UPDATE event should be dispatched to |v1|
+ // directly.
+ GestureEventForTest scroll_update(ui::ET_GESTURE_SCROLL_UPDATE, 5, 5);
+ widget->OnGestureEvent(&scroll_update);
+ EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
+ EXPECT_EQ(v1, GetGestureHandler(root_view));
+ EXPECT_TRUE(scroll_update.handled());
+ v1->ResetCounts();
+ v2->ResetCounts();
+ v3->ResetCounts();
+ v4->ResetCounts();
+
+ // A ui::ET_GESTURE_SCROLL_END event should be dispatched to |v1|
+ // directly and should not reset the gesture handler.
+ GestureEventForTest scroll_end(ui::ET_GESTURE_SCROLL_END, 5, 5);
+ widget->OnGestureEvent(&scroll_end);
+ EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_SCROLL_END));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SCROLL_END));
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_SCROLL_END));
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_END));
+ EXPECT_EQ(v1, GetGestureHandler(root_view));
+ EXPECT_TRUE(scroll_end.handled());
+ v1->ResetCounts();
+ v2->ResetCounts();
+ v3->ResetCounts();
+ v4->ResetCounts();
+
+ // A ui::ET_GESTURE_PINCH_BEGIN event (which is a non-scroll event) should
+ // still be dispatched to |v1| directly.
+ GestureEventForTest pinch_begin(ui::ET_GESTURE_PINCH_BEGIN, 5, 5);
+ widget->OnGestureEvent(&pinch_begin);
+ EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
+ EXPECT_EQ(v1, GetGestureHandler(root_view));
+ EXPECT_TRUE(pinch_begin.handled());
+ v1->ResetCounts();
+ v2->ResetCounts();
+ v3->ResetCounts();
+ v4->ResetCounts();
+
+ // A ui::ET_GESTURE_END event should not be dispatched to any view and should
+ // set the gesture handler to NULL.
+ GestureEventForTest end(ui::ET_GESTURE_END, 5, 5);
+ widget->OnGestureEvent(&end);
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
+ EXPECT_EQ(NULL, GetGestureHandler(root_view));
+ EXPECT_FALSE(end.handled());
+
+ widget->Close();
+}
+
// Test the result of Widget::GetAllChildWidgets().
TEST_F(WidgetTest, GetAllChildWidgets) {
// Create the following widget hierarchy:
« ui/views/controls/slider.cc ('K') | « ui/views/widget/widget_interactive_uitest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698