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 3 // found in the LICENSE file. 4 5 #include "ui/views/corewm/compound_event_filter.h" 6 7 #include "ui/aura/client/activation_client.h" 8 #include "ui/aura/client/cursor_client.h" 9 #include "ui/aura/env.h" 10 #include "ui/aura/root_window.h" 11 #include "ui/aura/test/aura_test_base.h" 12 #include "ui/aura/test/event_generator.h" 13 #include "ui/aura/test/test_activation_client.h" 14 #include "ui/aura/test/test_cursor_client.h" 15 #include "ui/aura/test/test_windows.h" 16 #include "ui/base/events/event.h" 17 #include "ui/base/events/event_utils.h" 18 19 namespace { 20 21 base::TimeDelta GetTime() { 22 return ui::EventTimeForNow(); 23 } 24 25 } 26 27 namespace views { 28 namespace corewm { 29 30 namespace { 31 32 // An event filter that consumes all gesture events. 33 class ConsumeGestureEventFilter : public ui::EventHandler { 34 public: 35 ConsumeGestureEventFilter() {} 36 virtual ~ConsumeGestureEventFilter() {} 37 38 private: 39 // Overridden from ui::EventHandler: 40 virtual void OnGestureEvent(ui::GestureEvent* e) OVERRIDE { 41 e->StopPropagation(); 42 } 43 44 DISALLOW_COPY_AND_ASSIGN(ConsumeGestureEventFilter); 45 }; 46 47 } // namespace 48 49 typedef aura::test::AuraTestBase CompoundEventFilterTest; 50 51 TEST_F(CompoundEventFilterTest, CursorVisibilityChange) { 52 scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter); 53 aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get()); 54 aura::test::TestWindowDelegate delegate; 55 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234, 56 gfx::Rect(5, 5, 100, 100), root_window())); 57 window->Show(); 58 window->SetCapture(); 59 60 aura::test::TestCursorClient cursor_client(root_window()); 61 62 // Send key event to hide the cursor. 63 ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_A, 0, true); 64 root_window()->AsRootWindowHostDelegate()->OnHostKeyEvent(&key); 65 EXPECT_FALSE(cursor_client.IsCursorVisible()); 66 67 // Synthesized mouse event should not show the cursor. 68 ui::MouseEvent enter(ui::ET_MOUSE_ENTERED, gfx::Point(10, 10), 69 gfx::Point(10, 10), 0); 70 enter.set_flags(enter.flags() | ui::EF_IS_SYNTHESIZED); 71 root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&enter); 72 EXPECT_FALSE(cursor_client.IsCursorVisible()); 73 74 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), 75 gfx::Point(10, 10), 0); 76 move.set_flags(enter.flags() | ui::EF_IS_SYNTHESIZED); 77 root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&move); 78 EXPECT_FALSE(cursor_client.IsCursorVisible()); 79 80 ui::MouseEvent real_move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), 81 gfx::Point(10, 10), 0); 82 root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&real_move); 83 EXPECT_TRUE(cursor_client.IsCursorVisible()); 84 85 // Send key event to hide the cursor again. 86 root_window()->AsRootWindowHostDelegate()->OnHostKeyEvent(&key); 87 EXPECT_FALSE(cursor_client.IsCursorVisible()); 88 89 // Mouse synthesized exit event should not show the cursor. 90 ui::MouseEvent exit(ui::ET_MOUSE_EXITED, gfx::Point(10, 10), 91 gfx::Point(10, 10), 0); 92 exit.set_flags(enter.flags() | ui::EF_IS_SYNTHESIZED); 93 root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&exit); 94 EXPECT_FALSE(cursor_client.IsCursorVisible()); 95 } 96 97 TEST_F(CompoundEventFilterTest, TouchHidesCursor) { 98 scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter); 99 aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get()); 100 aura::test::TestWindowDelegate delegate; 101 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234, 102 gfx::Rect(5, 5, 100, 100), root_window())); 103 window->Show(); 104 window->SetCapture(); 105 106 aura::test::TestCursorClient cursor_client(root_window()); 107 108 ui::MouseEvent mouse0(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), 109 gfx::Point(10, 10), 0); 110 root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse0); 111 EXPECT_TRUE(cursor_client.IsMouseEventsEnabled()); 112 113 // This press is required for the GestureRecognizer to associate a target 114 // with kTouchId 115 ui::TouchEvent press0( 116 ui::ET_TOUCH_PRESSED, gfx::Point(90, 90), 1, GetTime()); 117 root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press0); 118 EXPECT_FALSE(cursor_client.IsMouseEventsEnabled()); 119 120 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 10), 1, GetTime()); 121 root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); 122 EXPECT_FALSE(cursor_client.IsMouseEventsEnabled()); 123 124 ui::TouchEvent release( 125 ui::ET_TOUCH_RELEASED, gfx::Point(10, 10), 1, GetTime()); 126 root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); 127 EXPECT_FALSE(cursor_client.IsMouseEventsEnabled()); 128 129 ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), 130 gfx::Point(10, 10), 0); 131 // Move the cursor again. The cursor should be visible. 132 root_window()->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse1); 133 EXPECT_TRUE(cursor_client.IsMouseEventsEnabled()); 134 135 // Now activate the window and press on it again. 136 ui::TouchEvent press1( 137 ui::ET_TOUCH_PRESSED, gfx::Point(90, 90), 1, GetTime()); 138 aura::client::GetActivationClient( 139 root_window())->ActivateWindow(window.get()); 140 root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); 141 EXPECT_FALSE(cursor_client.IsMouseEventsEnabled()); 142 aura::Env::GetInstance()->RemovePreTargetHandler(compound_filter.get()); 143 } 144 145 // Tests that if an event filter consumes a gesture, then it doesn't focus the 146 // window. 147 TEST_F(CompoundEventFilterTest, FilterConsumedGesture) { 148 scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter); 149 scoped_ptr<ui::EventHandler> gesure_handler(new ConsumeGestureEventFilter); 150 compound_filter->AddHandler(gesure_handler.get()); 151 aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get()); 152 aura::test::TestWindowDelegate delegate; 153 DCHECK(root_window()); 154 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234, 155 gfx::Rect(5, 5, 100, 100), root_window())); 156 window->Show(); 157 158 EXPECT_TRUE(window->CanFocus()); 159 EXPECT_FALSE(window->HasFocus()); 160 161 // Tap on the window should not focus it since the filter will be consuming 162 // the gestures. 163 aura::test::EventGenerator generator(root_window(), gfx::Point(50, 50)); 164 generator.PressTouch(); 165 EXPECT_FALSE(window->HasFocus()); 166 167 compound_filter->RemoveHandler(gesure_handler.get()); 168 aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get()); 169 } 170 171 // Verifies we don't attempt to hide the mouse when the mouse is down and a 172 // touch event comes in. 173 TEST_F(CompoundEventFilterTest, DontHideWhenMouseDown) { 174 aura::test::EventGenerator event_generator(root_window()); 175 176 scoped_ptr<CompoundEventFilter> compound_filter(new CompoundEventFilter); 177 aura::Env::GetInstance()->AddPreTargetHandler(compound_filter.get()); 178 aura::test::TestWindowDelegate delegate; 179 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(&delegate, 1234, 180 gfx::Rect(5, 5, 100, 100), root_window())); 181 window->Show(); 182 183 aura::test::TestCursorClient cursor_client(root_window()); 184 185 // Move and press the mouse over the window. 186 event_generator.MoveMouseTo(10, 10); 187 EXPECT_TRUE(cursor_client.IsMouseEventsEnabled()); 188 event_generator.PressLeftButton(); 189 EXPECT_TRUE(cursor_client.IsMouseEventsEnabled()); 190 EXPECT_TRUE(aura::Env::GetInstance()->is_mouse_button_down()); 191 192 // Do a touch event. As the mouse button is down this should not disable mouse 193 // events. 194 event_generator.PressTouch(); 195 EXPECT_TRUE(cursor_client.IsMouseEventsEnabled()); 196 aura::Env::GetInstance()->RemovePreTargetHandler(compound_filter.get()); 197 } 198 199 } // namespace corewm 200 } // namespace views 201