OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <set> | 6 #include <set> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 #include "ui/aura/test/event_generator.h" | |
16 #include "ui/aura/window.h" | |
17 #include "ui/base/hit_test.h" | 15 #include "ui/base/hit_test.h" |
18 #include "ui/compositor/layer_animation_observer.h" | 16 #include "ui/compositor/layer_animation_observer.h" |
19 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 17 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
20 #include "ui/compositor/scoped_layer_animation_settings.h" | 18 #include "ui/compositor/scoped_layer_animation_settings.h" |
21 #include "ui/events/event_processor.h" | 19 #include "ui/events/event_processor.h" |
22 #include "ui/events/event_utils.h" | 20 #include "ui/events/event_utils.h" |
23 #include "ui/gfx/native_widget_types.h" | 21 #include "ui/gfx/native_widget_types.h" |
24 #include "ui/gfx/point.h" | 22 #include "ui/gfx/point.h" |
25 #include "ui/views/bubble/bubble_delegate.h" | 23 #include "ui/views/bubble/bubble_delegate.h" |
26 #include "ui/views/controls/textfield/textfield.h" | 24 #include "ui/views/controls/textfield/textfield.h" |
27 #include "ui/views/test/test_views_delegate.h" | 25 #include "ui/views/test/test_views_delegate.h" |
| 26 #include "ui/views/test/widget_event_generator.h" |
28 #include "ui/views/test/widget_test.h" | 27 #include "ui/views/test/widget_test.h" |
29 #include "ui/views/views_delegate.h" | 28 #include "ui/views/views_delegate.h" |
30 #include "ui/views/widget/native_widget_delegate.h" | 29 #include "ui/views/widget/native_widget_delegate.h" |
31 #include "ui/views/widget/root_view.h" | 30 #include "ui/views/widget/root_view.h" |
32 #include "ui/views/widget/widget_deletion_observer.h" | 31 #include "ui/views/widget/widget_deletion_observer.h" |
33 #include "ui/views/window/dialog_delegate.h" | 32 #include "ui/views/window/dialog_delegate.h" |
34 #include "ui/views/window/native_frame_view.h" | 33 #include "ui/views/window/native_frame_view.h" |
35 | 34 |
36 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
37 #include "ui/views/win/hwnd_util.h" | 36 #include "ui/views/win/hwnd_util.h" |
38 #endif | 37 #endif |
39 | 38 |
40 namespace views { | 39 namespace views { |
41 namespace test { | 40 namespace test { |
42 | 41 |
43 // A view that keeps track of the events it receives, but consumes no events. | 42 // A view that keeps track of the events it receives, optionally consuming them. |
44 class EventCountView : public View { | 43 class EventCountView : public View { |
45 public: | 44 public: |
46 EventCountView() {} | 45 // Whether to call SetHandled() on events as they are received. For some event |
| 46 // types, this will allow EventCountView to receives future events in the |
| 47 // event sequence, such as a drag. |
| 48 enum HandleMode { |
| 49 PROPAGATE_EVENTS, |
| 50 CONSUME_EVENTS |
| 51 }; |
| 52 |
| 53 EventCountView() |
| 54 : last_flags_(0), |
| 55 handle_mode_(PROPAGATE_EVENTS) {} |
| 56 |
47 virtual ~EventCountView() {} | 57 virtual ~EventCountView() {} |
48 | 58 |
49 int GetEventCount(ui::EventType type) { | 59 int GetEventCount(ui::EventType type) { |
50 return event_count_[type]; | 60 return event_count_[type]; |
51 } | 61 } |
52 | 62 |
53 void ResetCounts() { | 63 void ResetCounts() { |
54 event_count_.clear(); | 64 event_count_.clear(); |
55 } | 65 } |
56 | 66 |
| 67 int last_flags() const { |
| 68 return last_flags_; |
| 69 } |
| 70 |
| 71 void set_handle_mode(HandleMode handle_mode) { |
| 72 handle_mode_ = handle_mode; |
| 73 } |
| 74 |
57 protected: | 75 protected: |
| 76 // Overridden from View: |
| 77 virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE { |
| 78 // MouseMove events are not re-dispatched from the RootView. |
| 79 ++event_count_[ui::ET_MOUSE_MOVED]; |
| 80 last_flags_ = 0; |
| 81 } |
| 82 |
58 // Overridden from ui::EventHandler: | 83 // Overridden from ui::EventHandler: |
59 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { | 84 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { |
60 RecordEvent(*event); | 85 RecordEvent(event); |
61 } | 86 } |
62 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { | 87 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { |
63 RecordEvent(*event); | 88 RecordEvent(event); |
64 } | 89 } |
65 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { | 90 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { |
66 RecordEvent(*event); | 91 RecordEvent(event); |
67 } | 92 } |
68 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { | 93 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { |
69 RecordEvent(*event); | 94 RecordEvent(event); |
70 } | 95 } |
71 | 96 |
72 private: | 97 private: |
73 void RecordEvent(const ui::Event& event) { | 98 void RecordEvent(ui::Event* event) { |
74 ++event_count_[event.type()]; | 99 ++event_count_[event->type()]; |
| 100 last_flags_ = event->flags(); |
| 101 if (handle_mode_ == CONSUME_EVENTS) |
| 102 event->SetHandled(); |
75 } | 103 } |
76 | 104 |
77 std::map<ui::EventType, int> event_count_; | 105 std::map<ui::EventType, int> event_count_; |
| 106 int last_flags_; |
| 107 HandleMode handle_mode_; |
78 | 108 |
79 DISALLOW_COPY_AND_ASSIGN(EventCountView); | 109 DISALLOW_COPY_AND_ASSIGN(EventCountView); |
80 }; | 110 }; |
81 | 111 |
82 // A view that keeps track of the events it receives, and consumes all scroll | 112 // A view that keeps track of the events it receives, and consumes all scroll |
83 // gesture events and ui::ET_SCROLL events. | 113 // gesture events and ui::ET_SCROLL events. |
84 class ScrollableEventCountView : public EventCountView { | 114 class ScrollableEventCountView : public EventCountView { |
85 public: | 115 public: |
86 ScrollableEventCountView() {} | 116 ScrollableEventCountView() {} |
87 virtual ~ScrollableEventCountView() {} | 117 virtual ~ScrollableEventCountView() {} |
(...skipping 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1575 Widget* widget = new Widget; | 1605 Widget* widget = new Widget; |
1576 Widget::InitParams params = | 1606 Widget::InitParams params = |
1577 CreateParams(views::Widget::InitParams::TYPE_POPUP); | 1607 CreateParams(views::Widget::InitParams::TYPE_POPUP); |
1578 widget->Init(params); | 1608 widget->Init(params); |
1579 | 1609 |
1580 widget->SetContentsView(new CloseWidgetView(ui::ET_MOUSE_PRESSED)); | 1610 widget->SetContentsView(new CloseWidgetView(ui::ET_MOUSE_PRESSED)); |
1581 | 1611 |
1582 widget->SetSize(gfx::Size(100, 100)); | 1612 widget->SetSize(gfx::Size(100, 100)); |
1583 widget->Show(); | 1613 widget->Show(); |
1584 | 1614 |
1585 aura::test::EventGenerator generator(GetContext(), widget->GetNativeWindow()); | 1615 test::WidgetEventGenerator generator(GetContext(), widget); |
1586 | 1616 |
1587 WidgetDeletionObserver deletion_observer(widget); | 1617 WidgetDeletionObserver deletion_observer(widget); |
1588 generator.ClickLeftButton(); | 1618 generator.ClickLeftButton(); |
1589 EXPECT_FALSE(deletion_observer.IsWidgetAlive()); | 1619 EXPECT_FALSE(deletion_observer.IsWidgetAlive()); |
1590 | 1620 |
1591 // Yay we did not crash! | 1621 // Yay we did not crash! |
1592 } | 1622 } |
1593 | 1623 |
1594 TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) { | 1624 TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) { |
1595 Widget* widget = new Widget; | 1625 Widget* widget = new Widget; |
1596 Widget::InitParams params = | 1626 Widget::InitParams params = |
1597 CreateParams(views::Widget::InitParams::TYPE_POPUP); | 1627 CreateParams(views::Widget::InitParams::TYPE_POPUP); |
1598 widget->Init(params); | 1628 widget->Init(params); |
1599 | 1629 |
1600 widget->SetContentsView(new CloseWidgetView(ui::ET_GESTURE_TAP_DOWN)); | 1630 widget->SetContentsView(new CloseWidgetView(ui::ET_GESTURE_TAP_DOWN)); |
1601 | 1631 |
1602 widget->SetSize(gfx::Size(100, 100)); | 1632 widget->SetSize(gfx::Size(100, 100)); |
1603 widget->Show(); | 1633 widget->Show(); |
1604 | 1634 |
1605 aura::test::EventGenerator generator(GetContext()); | 1635 test::WidgetEventGenerator generator(GetContext()); |
1606 | 1636 |
1607 WidgetDeletionObserver deletion_observer(widget); | 1637 WidgetDeletionObserver deletion_observer(widget); |
1608 generator.GestureTapAt(widget->GetWindowBoundsInScreen().CenterPoint()); | 1638 generator.GestureTapAt(widget->GetWindowBoundsInScreen().CenterPoint()); |
1609 EXPECT_FALSE(deletion_observer.IsWidgetAlive()); | 1639 EXPECT_FALSE(deletion_observer.IsWidgetAlive()); |
1610 | 1640 |
1611 // Yay we did not crash! | 1641 // Yay we did not crash! |
1612 } | 1642 } |
1613 | 1643 |
1614 // See description of RunGetNativeThemeFromDestructor() for details. | 1644 // See description of RunGetNativeThemeFromDestructor() for details. |
1615 class GetNativeThemeFromDestructorView : public WidgetDelegateView { | 1645 class GetNativeThemeFromDestructorView : public WidgetDelegateView { |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 2136 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
2107 | 2137 |
2108 { | 2138 { |
2109 Widget top_level_widget; | 2139 Widget top_level_widget; |
2110 top_level_widget.Init(init_params); | 2140 top_level_widget.Init(init_params); |
2111 top_level_widget.SetFullscreen(true); | 2141 top_level_widget.SetFullscreen(true); |
2112 EXPECT_EQ(top_level_widget.IsVisible(), | 2142 EXPECT_EQ(top_level_widget.IsVisible(), |
2113 IsNativeWindowVisible(top_level_widget.GetNativeWindow())); | 2143 IsNativeWindowVisible(top_level_widget.GetNativeWindow())); |
2114 top_level_widget.CloseNow(); | 2144 top_level_widget.CloseNow(); |
2115 } | 2145 } |
2116 | |
2117 #if !defined(OS_CHROMEOS) | 2146 #if !defined(OS_CHROMEOS) |
2118 { | 2147 { |
2119 Widget top_level_widget; | 2148 Widget top_level_widget; |
2120 init_params.native_widget = | 2149 init_params.native_widget = |
2121 new PlatformDesktopNativeWidget(&top_level_widget); | 2150 new PlatformDesktopNativeWidget(&top_level_widget); |
2122 top_level_widget.Init(init_params); | 2151 top_level_widget.Init(init_params); |
2123 top_level_widget.SetFullscreen(true); | 2152 top_level_widget.SetFullscreen(true); |
2124 EXPECT_EQ(top_level_widget.IsVisible(), | 2153 EXPECT_EQ(top_level_widget.IsVisible(), |
2125 IsNativeWindowVisible(top_level_widget.GetNativeWindow())); | 2154 IsNativeWindowVisible(top_level_widget.GetNativeWindow())); |
2126 top_level_widget.CloseNow(); | 2155 top_level_widget.CloseNow(); |
2127 } | 2156 } |
2128 #endif | 2157 #endif |
2129 } | 2158 } |
2130 | |
2131 #if defined(OS_WIN) | 2159 #if defined(OS_WIN) |
2132 | 2160 |
2133 // Provides functionality to test widget activation via an activation flag | 2161 // Provides functionality to test widget activation via an activation flag |
2134 // which can be set by an accessor. | 2162 // which can be set by an accessor. |
2135 class ModalWindowTestWidgetDelegate : public WidgetDelegate { | 2163 class ModalWindowTestWidgetDelegate : public WidgetDelegate { |
2136 public: | 2164 public: |
2137 ModalWindowTestWidgetDelegate() | 2165 ModalWindowTestWidgetDelegate() |
2138 : widget_(NULL), | 2166 : widget_(NULL), |
2139 can_activate_(true) {} | 2167 can_activate_(true) {} |
2140 | 2168 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2414 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 2442 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
2415 child_params.context = parent_widget.GetNativeView(); | 2443 child_params.context = parent_widget.GetNativeView(); |
2416 child_widget.Init(child_params); | 2444 child_widget.Init(child_params); |
2417 child_widget.AddObserver(&observer); | 2445 child_widget.AddObserver(&observer); |
2418 child_widget.Show(); | 2446 child_widget.Show(); |
2419 | 2447 |
2420 parent_widget.CloseNow(); | 2448 parent_widget.CloseNow(); |
2421 } | 2449 } |
2422 #endif // !defined(OS_CHROMEOS) | 2450 #endif // !defined(OS_CHROMEOS) |
2423 | 2451 |
| 2452 // Tests that events propagate through from the dispatcher with the correct |
| 2453 // event type, and that the different platforms behave the same. |
| 2454 TEST_F(WidgetTest, MouseEventTypesViaGenerator) { |
| 2455 EventCountView* view = new EventCountView; |
| 2456 view->set_handle_mode(EventCountView::CONSUME_EVENTS); |
| 2457 view->SetBounds(10, 10, 50, 40); |
| 2458 |
| 2459 Widget* widget = CreateTopLevelFramelessPlatformWidget(); |
| 2460 widget->GetRootView()->AddChildView(view); |
| 2461 |
| 2462 widget->SetBounds(gfx::Rect(0, 0, 100, 80)); |
| 2463 widget->Show(); |
| 2464 |
| 2465 test::WidgetEventGenerator generator(widget); |
| 2466 generator.set_current_location(gfx::Point(20, 20)); |
| 2467 |
| 2468 generator.ClickLeftButton(); |
| 2469 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_PRESSED)); |
| 2470 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_RELEASED)); |
| 2471 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, view->last_flags()); |
| 2472 |
| 2473 generator.PressRightButton(); |
| 2474 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_PRESSED)); |
| 2475 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_RELEASED)); |
| 2476 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, view->last_flags()); |
| 2477 |
| 2478 generator.ReleaseRightButton(); |
| 2479 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_PRESSED)); |
| 2480 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_RELEASED)); |
| 2481 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, view->last_flags()); |
| 2482 |
| 2483 // Test mouse move events. |
| 2484 EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_MOVED)); |
| 2485 EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_ENTERED)); |
| 2486 |
| 2487 // Move the mouse within the view (20, 20) -> (30, 30). |
| 2488 generator.MoveMouseTo(gfx::Point(30, 30)); |
| 2489 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_MOVED)); |
| 2490 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED)); |
| 2491 EXPECT_EQ(ui::EF_NONE, view->last_flags()); |
| 2492 |
| 2493 // Move it again - entered count shouldn't change. |
| 2494 generator.MoveMouseTo(gfx::Point(31, 31)); |
| 2495 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_MOVED)); |
| 2496 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED)); |
| 2497 EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_EXITED)); |
| 2498 |
| 2499 // Move it off the view. |
| 2500 generator.MoveMouseTo(gfx::Point(5, 5)); |
| 2501 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_MOVED)); |
| 2502 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED)); |
| 2503 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_EXITED)); |
| 2504 |
| 2505 // Move it back on. |
| 2506 generator.MoveMouseTo(gfx::Point(20, 20)); |
| 2507 EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_MOVED)); |
| 2508 EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_ENTERED)); |
| 2509 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_EXITED)); |
| 2510 |
| 2511 // Drargging. Cover HasCapture() and NativeWidgetPrivate::IsMouseButtonDown(). |
| 2512 generator.DragMouseTo(gfx::Point(40, 40)); |
| 2513 EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_PRESSED)); |
| 2514 EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_RELEASED)); |
| 2515 EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_DRAGGED)); |
| 2516 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, view->last_flags()); |
| 2517 |
| 2518 widget->CloseNow(); |
| 2519 } |
| 2520 |
2424 } // namespace test | 2521 } // namespace test |
2425 } // namespace views | 2522 } // namespace views |
OLD | NEW |