Index: ui/views/widget/widget_unittest.cc |
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc |
index c740f6e107d6136b8c61a33af0e6a5f09a744cba..96bf01207e478d1f366c4a7842e9017dd240a876 100644 |
--- a/ui/views/widget/widget_unittest.cc |
+++ b/ui/views/widget/widget_unittest.cc |
@@ -2348,6 +2348,142 @@ TEST_F(WidgetTest, ScrollGestureEventDispatch) { |
widget->Close(); |
} |
+// Verifies that disabled views are permitted to be set as the default gesture |
+// handler in RootView. Also verifies that gesture events targeted to a disabled |
+// view are not actually dispatched to the view, but are still marked as |
+// handled. |
+TEST_F(WidgetTest, DisabledGestureEventTarget) { |
+ 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(); |
+ |
+ // |v1|, |v2|, and |v3| all handle gesture events but |v3| is marked as |
+ // disabled. |
+ v1->set_handle_mode(EventCountView::CONSUME_EVENTS); |
+ v2->set_handle_mode(EventCountView::CONSUME_EVENTS); |
+ v3->set_handle_mode(EventCountView::CONSUME_EVENTS); |
+ v3->SetEnabled(false); |
+ |
+ // No gesture handler is set in the root view, so it should remain unset |
+ // after a GESTURE_END. The event is first dispatched to |v4| (which does |
+ // not want to handle the event) and is then targeted at |v3|. Since |v3| |
+ // is disabled, the event is not dispatched but is still marked as handled. |
+ 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(1, v4->GetEventCount(ui::ET_GESTURE_END)); |
+ EXPECT_EQ(NULL, GetGestureHandler(root_view)); |
+ EXPECT_TRUE(end.handled()); |
+ v1->ResetCounts(); |
+ v2->ResetCounts(); |
+ v3->ResetCounts(); |
+ v4->ResetCounts(); |
+ |
+ // No gesture handler is set in the root view. In this case the tap event |
+ // should be dispatched only to |v4|, the gesture handler should be set to |
+ // |v3|, and the event should be marked as handled. |
+ GestureEventForTest tap(ui::ET_GESTURE_TAP, 5, 5); |
+ widget->OnGestureEvent(&tap); |
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(v3, GetGestureHandler(root_view)); |
+ EXPECT_TRUE(tap.handled()); |
+ v1->ResetCounts(); |
+ v2->ResetCounts(); |
+ v3->ResetCounts(); |
+ v4->ResetCounts(); |
+ |
+ // A subsequent gesture event should be marked as handled but not dispatched. |
+ tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5); |
+ widget->OnGestureEvent(&tap); |
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(v3, GetGestureHandler(root_view)); |
+ EXPECT_TRUE(tap.handled()); |
+ v1->ResetCounts(); |
+ v2->ResetCounts(); |
+ v3->ResetCounts(); |
+ v4->ResetCounts(); |
+ |
+ // A GESTURE_END should reset the default gesture handler to NULL. It should |
+ // also not be dispatched to |v3| but still marked as handled. |
+ end = GestureEventForTest(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_TRUE(end.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 which are dispatched to it. |
+ v3->set_handle_mode(EventCountView::PROPAGATE_EVENTS); |
+ |
+ // No gesture handler is set in the root view. In this case the tap event |
+ // should be dispatched only to |v4| and the event should be marked as |
+ // handled. Furthermore, the gesture handler should be set to |
+ // |v3|; even though |v3| does not explicitly handle events, it is a |
+ // valid target for the tap event because it is disabled. |
+ tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5); |
+ widget->OnGestureEvent(&tap); |
+ EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP)); |
+ EXPECT_EQ(v3, GetGestureHandler(root_view)); |
+ EXPECT_TRUE(tap.handled()); |
+ v1->ResetCounts(); |
+ v2->ResetCounts(); |
+ v3->ResetCounts(); |
+ v4->ResetCounts(); |
+ |
+ // A GESTURE_END should reset the default gesture handler to NULL. It should |
+ // also not be dispatched to |v3| but still marked as handled. |
+ end = GestureEventForTest(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_TRUE(end.handled()); |
+ |
+ widget->Close(); |
+} |
+ |
// Test the result of Widget::GetAllChildWidgets(). |
TEST_F(WidgetTest, GetAllChildWidgets) { |
// Create the following widget hierarchy: |