1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/display/mouse_cursor_event_filter.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ui/aura/client/cursor_shape_client.h"
10 #include "ui/aura/env.h"
11 #include "ui/aura/test/test_windows.h"
12 #include "ui/base/cursor/cursor.h"
13 #include "ui/display/display_layout.h"
14 #include "ui/display/manager/display_manager.h"
15 #include "ui/display/test/display_manager_test_api.h"
16 #include "ui/events/test/event_generator.h"
17 #include "ui/wm/core/cursor_manager.h"
21 class MouseCursorEventFilterTest : public AshTestBase {
23 MouseCursorEventFilterTest() = default;
25 MouseCursorEventFilterTest(const MouseCursorEventFilterTest&) = delete;
26 MouseCursorEventFilterTest& operator=(const MouseCursorEventFilterTest&) =
29 ~MouseCursorEventFilterTest() override = default;
32 MouseCursorEventFilter* event_filter() {
33 return Shell::Get()->mouse_cursor_filter();
36 bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
37 return AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
42 // Verifies if the mouse pointer correctly moves to another display when there
44 TEST_F(MouseCursorEventFilterTest, WarpMouse) {
45 UpdateDisplay("500x400,500x400");
47 ASSERT_EQ(display::DisplayPlacement::RIGHT, Shell::Get()
49 ->GetCurrentDisplayLayout()
53 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 11)));
55 // Touch the right edge of the primary root window. Pointer should warp.
56 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
57 EXPECT_EQ("501,11", // by 2px.
58 aura::Env::GetInstance()->last_mouse_location().ToString());
60 // Touch the left edge of the secondary root window. Pointer should warp.
61 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 11)));
62 EXPECT_EQ("498,11", // by 2px.
63 aura::Env::GetInstance()->last_mouse_location().ToString());
65 // Touch the left edge of the primary root window.
66 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(0, 11)));
67 // Touch the top edge of the primary root window.
68 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 0)));
69 // Touch the bottom edge of the primary root window.
70 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 399)));
71 // Touch the right edge of the secondary root window.
72 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(999, 11)));
73 // Touch the top edge of the secondary root window.
74 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 0)));
75 // Touch the bottom edge of the secondary root window.
76 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 399)));
79 // Verifies if the mouse pointer correctly moves to another display even when
80 // two displays are not the same size.
81 TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) {
82 UpdateDisplay("500x400,600x500"); // the second one is larger.
84 ASSERT_EQ(display::DisplayPlacement::RIGHT, Shell::Get()
86 ->GetCurrentDisplayLayout()
90 // Touch the left edge of the secondary root window. Pointer should NOT warp
91 // because 1px left of (0, 500) is outside the primary root window.
92 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(501, 400)));
94 aura::Env::GetInstance()->last_mouse_location().ToString());
96 // Touch the left edge of the secondary root window. Pointer should warp
97 // because 1px left of (0, 480) is inside the primary root window.
98 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 380)));
99 EXPECT_EQ("498,380", // by 2px.
100 aura::Env::GetInstance()->last_mouse_location().ToString());
103 // Verifies if the mouse pointer correctly moves between displays with
104 // different scale factors. In native coords mode, there is no
105 // difference between drag and move.
106 TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplaysInNative) {
107 UpdateDisplay("500x400,600x500*2");
109 ASSERT_EQ(display::DisplayPlacement::RIGHT, Shell::Get()
111 ->GetCurrentDisplayLayout()
115 aura::Env::GetInstance()->SetLastMouseLocation(gfx::Point(900, 123));
117 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 123)));
119 aura::Env::GetInstance()->last_mouse_location().ToString());
120 // Touch the edge of 2nd display again and make sure it warps to
122 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 123)));
123 // TODO(oshima): Due to a bug in EventGenerator, the screen coordinates
124 // is shrunk by dsf once. Fix this.
126 aura::Env::GetInstance()->last_mouse_location().ToString());
129 // Verifies if MouseCursorEventFilter::set_mouse_warp_enabled() works as
131 TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) {
132 UpdateDisplay("500x400,500x400");
134 event_filter()->set_mouse_warp_enabled(false);
135 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
137 aura::Env::GetInstance()->last_mouse_location().ToString());
139 event_filter()->set_mouse_warp_enabled(true);
140 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
142 aura::Env::GetInstance()->last_mouse_location().ToString());
145 // Verifies cursor's image scale factor is updated when a cursor has moved
146 // across root windows with different device scale factors
147 // (http://crbug.com/154183).
148 TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) {
149 UpdateDisplay("400x300,800x700*2");
150 display_manager()->SetLayoutForCurrentDisplays(
151 display::test::CreateDisplayLayout(display_manager(),
152 display::DisplayPlacement::RIGHT, 0));
153 auto* cursor_manager = Shell::Get()->cursor_manager();
154 const auto& cursor_shape_client = aura::client::GetCursorShapeClient();
156 cursor_shape_client.GetCursorData(cursor_manager->GetCursor())
158 GetEventGenerator()->MoveMouseTo(401, 200);
160 cursor_shape_client.GetCursorData(cursor_manager->GetCursor())
162 GetEventGenerator()->MoveMouseTo(399, 200);
164 cursor_shape_client.GetCursorData(cursor_manager->GetCursor())
168 // Verifies that pressing the key repeatedly will not hide the cursor.
169 // Otherwise, in one edge case, user may press one key repeatedly while moving
170 // the cursor and then the user interface looks weird.
171 // (http://crbug.com/855163).
172 TEST_F(MouseCursorEventFilterTest, CursorVisibilityWontFlip) {
173 aura::test::TestWindowDelegate delegate;
174 std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
175 &delegate, 1234, gfx::Rect(5, 5, 100, 100)));
177 window->SetCapture();
179 wm::CursorManager* manager = Shell::Get()->cursor_manager();
181 // Cursor is visible at start
182 EXPECT_TRUE(manager->IsCursorVisible());
184 ui::test::EventGenerator* generator = GetEventGenerator();
186 // Pressing key will hide the cursor
187 generator->PressKey(ui::VKEY_A, ui::EF_NONE);
188 EXPECT_FALSE(manager->IsCursorVisible());
190 // Moving the mouse will show the cursor
191 generator->MoveMouseTo(gfx::Point(10, 10));
192 EXPECT_TRUE(manager->IsCursorVisible());
194 // Pressing key repeatedly will not hide the cursor
195 generator->PressKey(ui::VKEY_A, ui::EF_NONE | ui::EF_IS_REPEAT);
196 EXPECT_TRUE(manager->IsCursorVisible());