summaryrefslogtreecommitdiffstats
path: root/ash/display/cursor_window_controller_unittest.cc
blob: d1f94458d569da8a9bcb5ffa8f8fde114b409c41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright 2015 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/cursor_window_controller.h"

#include "ash/display/display_util.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/display_manager_test_api.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/display.h"
#include "ui/wm/core/coordinate_conversion.h"

namespace ash {

class CursorWindowControllerTest : public test::AshTestBase {
 public:
  CursorWindowControllerTest() {}
  ~CursorWindowControllerTest() override {}

  // test::AshTestBase:
  void SetUp() override {
    AshTestBase::SetUp();
    SetCursorCompositionEnabled(true);
  }

  int GetCursorType() const { return cursor_window_controller_->cursor_type_; }

  const gfx::Point& GetCursorHotPoint() const {
    return cursor_window_controller_->hot_point_;
  }

  aura::Window* GetCursorWindow() const {
    return cursor_window_controller_->cursor_window_.get();
  }

  const gfx::ImageSkia& GetCursorImage() const {
    return cursor_window_controller_->GetCursorImageForTest();
  }

  int64 GetCursorDisplayId() const {
    return cursor_window_controller_->display_.id();
  }

  void SetCursorCompositionEnabled(bool enabled) {
    cursor_window_controller_ = Shell::GetInstance()
                                    ->window_tree_host_manager()
                                    ->cursor_window_controller();
    cursor_window_controller_->SetCursorCompositingEnabled(enabled);
  }

 private:
  // Not owned.
  CursorWindowController* cursor_window_controller_;

  DISALLOW_COPY_AND_ASSIGN(CursorWindowControllerTest);
};

// Test that the composited cursor moves to another display when the real cursor
// moves to another display.
TEST_F(CursorWindowControllerTest, MoveToDifferentDisplay) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("200x200,200x200*2/r");

  WindowTreeHostManager* window_tree_host_manager =
      Shell::GetInstance()->window_tree_host_manager();
  int64 primary_display_id = window_tree_host_manager->GetPrimaryDisplayId();
  int64 secondary_display_id = ScreenUtil::GetSecondaryDisplay().id();
  aura::Window* primary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(primary_display_id);
  aura::Window* secondary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(secondary_display_id);

  ui::test::EventGenerator primary_generator(primary_root);
  primary_generator.MoveMouseToInHost(20, 50);

  EXPECT_TRUE(primary_root->Contains(GetCursorWindow()));
  EXPECT_EQ(primary_display_id, GetCursorDisplayId());
  EXPECT_EQ(ui::kCursorNull, GetCursorType());
  gfx::Point hot_point = GetCursorHotPoint();
  EXPECT_EQ("4,4", hot_point.ToString());
  gfx::Rect cursor_bounds = GetCursorWindow()->GetBoundsInScreen();
  EXPECT_EQ(20, cursor_bounds.x() + hot_point.x());
  EXPECT_EQ(50, cursor_bounds.y() + hot_point.y());

  // The cursor can only be moved between displays via
  // WindowTreeHost::MoveCursorTo(). EventGenerator uses a hack to move the
  // cursor between displays.
  // Screen location: 220, 50
  // Root location: 20, 50
  secondary_root->MoveCursorTo(gfx::Point(20, 50));

  // Chrome relies on WindowTreeHost::MoveCursorTo() dispatching a mouse move
  // asynchronously. This is implemented in a platform specific way. Generate a
  // fake mouse move instead of waiting.
  gfx::Point new_cursor_position_in_host(20, 50);
  secondary_root->GetHost()->ConvertPointToHost(&new_cursor_position_in_host);
  ui::test::EventGenerator secondary_generator(secondary_root);
  secondary_generator.MoveMouseToInHost(new_cursor_position_in_host);

  EXPECT_TRUE(secondary_root->Contains(GetCursorWindow()));
  EXPECT_EQ(secondary_display_id, GetCursorDisplayId());
  EXPECT_EQ(ui::kCursorNull, GetCursorType());
  hot_point = GetCursorHotPoint();
  EXPECT_EQ("3,3", hot_point.ToString());
  cursor_bounds = GetCursorWindow()->GetBoundsInScreen();
  EXPECT_EQ(220, cursor_bounds.x() + hot_point.x());
  EXPECT_EQ(50, cursor_bounds.y() + hot_point.y());
}

// Windows doesn't support compositor based cursor.
#if !defined(OS_WIN)
// Make sure that composition cursor inherits the visibility state.
TEST_F(CursorWindowControllerTest, VisibilityTest) {
  ASSERT_TRUE(GetCursorWindow());
  EXPECT_TRUE(GetCursorWindow()->IsVisible());
  aura::client::CursorClient* client = Shell::GetInstance()->cursor_manager();
  client->HideCursor();
  ASSERT_TRUE(GetCursorWindow());
  EXPECT_FALSE(GetCursorWindow()->IsVisible());

  // Normal cursor should be in the correct state.
  SetCursorCompositionEnabled(false);
  ASSERT_FALSE(GetCursorWindow());
  ASSERT_FALSE(client->IsCursorVisible());

  // Cursor was hidden.
  SetCursorCompositionEnabled(true);
  ASSERT_TRUE(GetCursorWindow());
  EXPECT_FALSE(GetCursorWindow()->IsVisible());

  // Goback to normal cursor and show the cursor.
  SetCursorCompositionEnabled(false);
  ASSERT_FALSE(GetCursorWindow());
  ASSERT_FALSE(client->IsCursorVisible());
  client->ShowCursor();
  ASSERT_TRUE(client->IsCursorVisible());

  // Cursor was shown.
  SetCursorCompositionEnabled(true);
  ASSERT_TRUE(GetCursorWindow());
  EXPECT_TRUE(GetCursorWindow()->IsVisible());
}

// Make sure that composition cursor stays big even when
// the DSF becomes 1x as a result of zooming out.
TEST_F(CursorWindowControllerTest, DSF) {
  UpdateDisplay("1000x500*2");
  int64 primary_id = Shell::GetScreen()->GetPrimaryDisplay().id();

  test::ScopedSetInternalDisplayId set_internal(primary_id);
  SetCursorCompositionEnabled(true);
  ASSERT_EQ(2.0f,
            Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_TRUE(GetCursorImage().HasRepresentation(2.0f));

  ASSERT_TRUE(SetDisplayUIScale(primary_id, 2.0f));
  ASSERT_EQ(1.0f,
            Shell::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_TRUE(GetCursorImage().HasRepresentation(2.0f));
}
#endif

}  // namespace ash