| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/display/mouse_cursor_event_filter.h" |
| |
| #include "ash/shell.h" |
| #include "ash/test/ash_test_base.h" |
| #include "ash/wm/cursor_manager_test_api.h" |
| #include "ui/aura/env.h" |
| #include "ui/aura/test/test_windows.h" |
| #include "ui/display/display_layout.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/display/test/display_manager_test_api.h" |
| #include "ui/events/test/event_generator.h" |
| |
| namespace ash { |
| |
| class MouseCursorEventFilterTest : public AshTestBase { |
| public: |
| MouseCursorEventFilterTest() = default; |
| ~MouseCursorEventFilterTest() override = default; |
| |
| protected: |
| MouseCursorEventFilter* event_filter() { |
| return Shell::Get()->mouse_cursor_filter(); |
| } |
| |
| bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) { |
| return AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(), |
| point_in_screen); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilterTest); |
| }; |
| |
| // Verifies if the mouse pointer correctly moves to another display when there |
| // are two displays. |
| TEST_F(MouseCursorEventFilterTest, WarpMouse) { |
| UpdateDisplay("500x500,500x500"); |
| |
| ASSERT_EQ(display::DisplayPlacement::RIGHT, Shell::Get() |
| ->display_manager() |
| ->GetCurrentDisplayLayout() |
| .placement_list[0] |
| .position); |
| |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 11))); |
| |
| // Touch the right edge of the primary root window. Pointer should warp. |
| EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11))); |
| EXPECT_EQ("501,11", // by 2px. |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| |
| // Touch the left edge of the secondary root window. Pointer should warp. |
| EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 11))); |
| EXPECT_EQ("498,11", // by 2px. |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| |
| // Touch the left edge of the primary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(0, 11))); |
| // Touch the top edge of the primary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 0))); |
| // Touch the bottom edge of the primary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 499))); |
| // Touch the right edge of the secondary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(999, 11))); |
| // Touch the top edge of the secondary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 0))); |
| // Touch the bottom edge of the secondary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(11, 499))); |
| } |
| |
| // Verifies if the mouse pointer correctly moves to another display even when |
| // two displays are not the same size. |
| TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) { |
| UpdateDisplay("500x500,600x600"); // the second one is larger. |
| |
| ASSERT_EQ(display::DisplayPlacement::RIGHT, Shell::Get() |
| ->display_manager() |
| ->GetCurrentDisplayLayout() |
| .placement_list[0] |
| .position); |
| |
| // Touch the left edge of the secondary root window. Pointer should NOT warp |
| // because 1px left of (0, 500) is outside the primary root window. |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(501, 500))); |
| EXPECT_EQ("501,500", |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| |
| // Touch the left edge of the secondary root window. Pointer should warp |
| // because 1px left of (0, 480) is inside the primary root window. |
| EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 480))); |
| EXPECT_EQ("498,480", // by 2px. |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| } |
| |
| // Verifies if the mouse pointer correctly moves between displays with |
| // different scale factors. In native coords mode, there is no |
| // difference between drag and move. |
| TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplaysInNative) { |
| UpdateDisplay("500x500,600x600*2"); |
| |
| ASSERT_EQ(display::DisplayPlacement::RIGHT, Shell::Get() |
| ->display_manager() |
| ->GetCurrentDisplayLayout() |
| .placement_list[0] |
| .position); |
| |
| Shell::Get()->aura_env()->SetLastMouseLocation(gfx::Point(900, 123)); |
| |
| EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 123))); |
| EXPECT_EQ("500,123", |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| // Touch the edge of 2nd display again and make sure it warps to |
| // 1st dislay. |
| EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 123))); |
| // TODO(oshima): Due to a bug in EventGenerator, the screen coordinates |
| // is shrunk by dsf once. Fix this. |
| EXPECT_EQ("498,61", |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| } |
| |
| // Verifies if MouseCursorEventFilter::set_mouse_warp_enabled() works as |
| // expected. |
| TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) { |
| UpdateDisplay("500x500,500x500"); |
| |
| event_filter()->set_mouse_warp_enabled(false); |
| EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(499, 11))); |
| EXPECT_EQ("499,11", |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| |
| event_filter()->set_mouse_warp_enabled(true); |
| EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11))); |
| EXPECT_EQ("501,11", |
| Shell::Get()->aura_env()->last_mouse_location().ToString()); |
| } |
| |
| // Verifies cursor's device scale factor is updated when a cursor has moved |
| // across root windows with different device scale factors |
| // (http://crbug.com/154183). |
| TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) { |
| UpdateDisplay("400x400,800x800*2"); |
| display_manager()->SetLayoutForCurrentDisplays( |
| display::test::CreateDisplayLayout(display_manager(), |
| display::DisplayPlacement::RIGHT, 0)); |
| CursorManagerTestApi cursor_test_api(Shell::Get()->cursor_manager()); |
| |
| EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
| TestIfMouseWarpsAt(gfx::Point(399, 200)); |
| EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
| TestIfMouseWarpsAt(gfx::Point(400, 200)); |
| EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor()); |
| } |
| |
| // Verifies that pressing the key repeatedly will not hide the cursor. |
| // Otherwise, in one edge case, user may press one key repeatedly while moving |
| // the cursor and then the user interface looks weird. |
| // (http://crbug.com/855163). |
| TEST_F(MouseCursorEventFilterTest, CursorVisibilityWontFlip) { |
| aura::test::TestWindowDelegate delegate; |
| std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( |
| &delegate, 1234, gfx::Rect(5, 5, 100, 100))); |
| window->Show(); |
| window->SetCapture(); |
| |
| wm::CursorManager* manager = Shell::Get()->cursor_manager(); |
| |
| // Cursor is visible at start |
| EXPECT_TRUE(manager->IsCursorVisible()); |
| |
| ui::test::EventGenerator* generator = GetEventGenerator(); |
| |
| // Pressing key will hide the cursor |
| generator->PressKey(ui::VKEY_A, ui::EF_NONE); |
| EXPECT_FALSE(manager->IsCursorVisible()); |
| |
| // Moving the mouse will show the cursor |
| generator->MoveMouseTo(gfx::Point(10, 10)); |
| EXPECT_TRUE(manager->IsCursorVisible()); |
| |
| // Pressing key repeatedly will not hide the cursor |
| generator->PressKey(ui::VKEY_A, ui::EF_NONE | ui::EF_IS_REPEAT); |
| EXPECT_TRUE(manager->IsCursorVisible()); |
| } |
| |
| } // namespace ash |