1 // Copyright 2015 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.
5 #include "ash/display/cursor_window_controller.h"
7 #include "ash/display/display_controller.h"
8 #include "ash/screen_util.h"
10 #include "ash/test/ash_test_base.h"
11 #include "ui/aura/window.h"
12 #include "ui/aura/window_tree_host.h"
13 #include "ui/base/cursor/cursor.h"
14 #include "ui/events/test/event_generator.h"
15 #include "ui/gfx/display.h"
16 #include "ui/wm/core/coordinate_conversion.h"
20 class CursorWindowControllerTest
: public test::AshTestBase
{
22 CursorWindowControllerTest() {}
23 ~CursorWindowControllerTest() override
{}
26 void SetUp() override
{
28 SetCursorCompositionEnabled(true);
31 int GetCursorType() const { return cursor_window_controller_
->cursor_type_
; }
33 const gfx::Point
& GetCursorHotPoint() const {
34 return cursor_window_controller_
->hot_point_
;
37 aura::Window
* GetCursorWindow() const {
38 return cursor_window_controller_
->cursor_window_
.get();
41 int64
GetCursorDisplayId() const {
42 return cursor_window_controller_
->display_
.id();
45 void SetCursorCompositionEnabled(bool enabled
) {
46 cursor_window_controller_
=
47 Shell::GetInstance()->display_controller()->cursor_window_controller();
48 cursor_window_controller_
->SetCursorCompositingEnabled(enabled
);
53 CursorWindowController
* cursor_window_controller_
;
55 DISALLOW_COPY_AND_ASSIGN(CursorWindowControllerTest
);
58 // Test that the composited cursor moves to another display when the real cursor
59 // moves to another display.
60 TEST_F(CursorWindowControllerTest
, MoveToDifferentDisplay
) {
61 if (!SupportsMultipleDisplays())
64 UpdateDisplay("200x200,200x200*2/r");
66 DisplayController
* display_controller
=
67 Shell::GetInstance()->display_controller();
68 int64 primary_display_id
= display_controller
->GetPrimaryDisplayId();
69 int64 secondary_display_id
= ScreenUtil::GetSecondaryDisplay().id();
70 aura::Window
* primary_root
=
71 display_controller
->GetRootWindowForDisplayId(primary_display_id
);
72 aura::Window
* secondary_root
=
73 display_controller
->GetRootWindowForDisplayId(secondary_display_id
);
75 ui::test::EventGenerator
primary_generator(primary_root
);
76 primary_generator
.MoveMouseToInHost(20, 50);
78 EXPECT_TRUE(primary_root
->Contains(GetCursorWindow()));
79 EXPECT_EQ(primary_display_id
, GetCursorDisplayId());
80 EXPECT_EQ(ui::kCursorNull
, GetCursorType());
81 gfx::Point hot_point
= GetCursorHotPoint();
82 EXPECT_EQ("4,4", hot_point
.ToString());
83 gfx::Rect cursor_bounds
= GetCursorWindow()->GetBoundsInScreen();
84 EXPECT_EQ(20, cursor_bounds
.x() + hot_point
.x());
85 EXPECT_EQ(50, cursor_bounds
.y() + hot_point
.y());
87 // The cursor can only be moved between displays via
88 // WindowTreeHost::MoveCursorTo(). EventGenerator uses a hack to move the
89 // cursor between displays.
90 // Screen location: 220, 50
91 // Root location: 20, 50
92 secondary_root
->MoveCursorTo(gfx::Point(20, 50));
94 // Chrome relies on WindowTreeHost::MoveCursorTo() dispatching a mouse move
95 // asynchronously. This is implemented in a platform specific way. Generate a
96 // fake mouse move instead of waiting.
97 gfx::Point
new_cursor_position_in_host(20, 50);
98 secondary_root
->GetHost()->ConvertPointToHost(&new_cursor_position_in_host
);
99 ui::test::EventGenerator
secondary_generator(secondary_root
);
100 secondary_generator
.MoveMouseToInHost(new_cursor_position_in_host
);
102 EXPECT_TRUE(secondary_root
->Contains(GetCursorWindow()));
103 EXPECT_EQ(secondary_display_id
, GetCursorDisplayId());
104 EXPECT_EQ(ui::kCursorNull
, GetCursorType());
105 hot_point
= GetCursorHotPoint();
106 EXPECT_EQ("8,9", hot_point
.ToString());
107 cursor_bounds
= GetCursorWindow()->GetBoundsInScreen();
108 EXPECT_EQ(220, cursor_bounds
.x() + hot_point
.x());
109 EXPECT_EQ(50, cursor_bounds
.y() + hot_point
.y());
112 // Windows doesn't support compositor based cursor.
114 // Make sure that composition cursor inherits the visibility state.
115 TEST_F(CursorWindowControllerTest
, VisibilityTest
) {
116 ASSERT_TRUE(GetCursorWindow());
117 EXPECT_TRUE(GetCursorWindow()->IsVisible());
118 aura::client::CursorClient
* client
= Shell::GetInstance()->cursor_manager();
119 client
->HideCursor();
120 ASSERT_TRUE(GetCursorWindow());
121 EXPECT_FALSE(GetCursorWindow()->IsVisible());
123 // Normal cursor should be in the correct state.
124 SetCursorCompositionEnabled(false);
125 ASSERT_FALSE(GetCursorWindow());
126 ASSERT_FALSE(client
->IsCursorVisible());
128 // Cursor was hidden.
129 SetCursorCompositionEnabled(true);
130 ASSERT_TRUE(GetCursorWindow());
131 EXPECT_FALSE(GetCursorWindow()->IsVisible());
133 // Goback to normal cursor and show the cursor.
134 SetCursorCompositionEnabled(false);
135 ASSERT_FALSE(GetCursorWindow());
136 ASSERT_FALSE(client
->IsCursorVisible());
137 client
->ShowCursor();
138 ASSERT_TRUE(client
->IsCursorVisible());
141 SetCursorCompositionEnabled(true);
142 ASSERT_TRUE(GetCursorWindow());
143 EXPECT_TRUE(GetCursorWindow()->IsVisible());