blob: d99f540a9c2fff5d16dde5efa29f9feade7bf786 [file] [log] [blame]
oshima83e6f6f2015-04-24 00:30:281// 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.
4
5#include "ash/display/extended_mouse_warp_controller.h"
6
oshima83e6f6f2015-04-24 00:30:287#include "ash/display/mouse_cursor_event_filter.h"
Andrew Xua6cdb0f02018-12-06 17:56:388#include "ash/display/screen_position_controller.h"
9#include "ash/host/ash_window_tree_host_platform.h"
oshima83e6f6f2015-04-24 00:30:2810#include "ash/shell.h"
11#include "ash/test/ash_test_base.h"
Andrew Xua6cdb0f02018-12-06 17:56:3812#include "ui/aura/env.h"
13#include "ui/aura/test/test_windows.h"
14#include "ui/aura/window_tree_host.h"
15#include "ui/base/hit_test.h"
oshimaf84b0da722016-04-27 19:47:1916#include "ui/display/display.h"
kylechar731f85f92016-12-01 20:50:4617#include "ui/display/display_layout.h"
18#include "ui/display/display_layout_builder.h"
rjkroege72f8154f2016-10-29 00:49:0219#include "ui/display/manager/display_manager.h"
oshimaf84b0da722016-04-27 19:47:1920#include "ui/display/screen.h"
rjkroege72f8154f2016-10-29 00:49:0221#include "ui/display/test/display_manager_test_api.h"
Andrew Xua6cdb0f02018-12-06 17:56:3822#include "ui/events/base_event_utils.h"
oshima83e6f6f2015-04-24 00:30:2823#include "ui/events/test/event_generator.h"
Andrew Xua6cdb0f02018-12-06 17:56:3824#include "ui/wm/core/coordinate_conversion.h"
oshima83e6f6f2015-04-24 00:30:2825
26namespace ash {
27
James Cook317781a2017-07-18 02:08:0628class ExtendedMouseWarpControllerTest : public AshTestBase {
oshima83e6f6f2015-04-24 00:30:2829 public:
Chris Watkinsc24daf62017-11-28 03:43:0930 ExtendedMouseWarpControllerTest() = default;
31 ~ExtendedMouseWarpControllerTest() override = default;
oshima83e6f6f2015-04-24 00:30:2832
33 protected:
34 MouseCursorEventFilter* event_filter() {
skycb4be5b2017-04-06 17:52:4535 return Shell::Get()->mouse_cursor_filter();
oshima83e6f6f2015-04-24 00:30:2836 }
37
38 ExtendedMouseWarpController* mouse_warp_controller() {
39 return static_cast<ExtendedMouseWarpController*>(
40 event_filter()->mouse_warp_controller_for_test());
41 }
42
oshima77570cb2016-03-24 21:33:2343 size_t GetWarpRegionsCount() {
44 return mouse_warp_controller()->warp_regions_.size();
45 }
46
47 const ExtendedMouseWarpController::WarpRegion* GetWarpRegion(size_t index) {
48 return mouse_warp_controller()->warp_regions_[index].get();
49 }
50
51 const gfx::Rect& GetIndicatorBounds(int64_t id) {
52 return GetWarpRegion(0)->GetIndicatorBoundsForTest(id);
53 }
54
Andrew Xua6cdb0f02018-12-06 17:56:3855 const gfx::Rect& GetIndicatorNativeBounds(int64_t id) {
56 return GetWarpRegion(0)->GetIndicatorNativeBoundsForTest(id);
57 }
58
59 // Send mouse event with native event through AshWindowTreeHostPlatform.
60 void DispatchMouseEventWithNative(AshWindowTreeHostPlatform* host,
61 const gfx::Point& location_in_host_native,
62 ui::EventType event_type,
63 int event_flag1,
64 int event_flag2) {
65 ui::MouseEvent native_event(event_type, location_in_host_native,
66 location_in_host_native, ui::EventTimeForNow(),
67 event_flag1, event_flag2);
68 ui::MouseEvent mouseev(&native_event);
Mike Wasserman4fe29ffa2018-12-15 03:00:5369 host->DispatchEvent(&mouseev);
Andrew Xua6cdb0f02018-12-06 17:56:3870
71 // The test relies on the last_mouse_location, which will be updated by
72 // a synthesized event posted asynchronusly. Wait until the synthesized
73 // event is handled and last mouse location is updated.
74 base::RunLoop().RunUntilIdle();
75 }
76
oshima83e6f6f2015-04-24 00:30:2877 private:
78 DISALLOW_COPY_AND_ASSIGN(ExtendedMouseWarpControllerTest);
79};
80
81// Verifies if MouseCursorEventFilter's bounds calculation works correctly.
82TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnRight) {
oshima83e6f6f2015-04-24 00:30:2883 UpdateDisplay("360x360,700x700");
84 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
oshimaf84b0da722016-04-27 19:47:1985 int64_t display_0_id = display::Screen::GetScreen()
86 ->GetDisplayNearestWindow(root_windows[0])
87 .id();
88 int64_t display_1_id = display::Screen::GetScreen()
89 ->GetDisplayNearestWindow(root_windows[1])
90 .id();
oshima83e6f6f2015-04-24 00:30:2891
rjkroege72f8154f2016-10-29 00:49:0292 std::unique_ptr<display::DisplayLayout> layout(
93 display::test::CreateDisplayLayout(display_manager(),
94 display::DisplayPlacement::RIGHT, 0));
oshima77570cb2016-03-24 21:33:2395
rjkroege980ccfd2016-10-06 18:00:2496 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:2897 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
jdufaultfb0a42122016-01-21 21:40:4198
oshima77570cb2016-03-24 21:33:2399 ASSERT_EQ(1U, GetWarpRegionsCount());
Qiang Xu47a567e2018-03-17 01:41:37100 EXPECT_EQ(gfx::Rect(359, 32, 1, 328), GetIndicatorBounds(display_0_id));
oshima77570cb2016-03-24 21:33:23101 EXPECT_EQ(gfx::Rect(360, 0, 1, 360), GetIndicatorBounds(display_1_id));
102
oshima83e6f6f2015-04-24 00:30:28103 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23104 EXPECT_EQ(gfx::Rect(359, 0, 1, 360), GetIndicatorBounds(display_0_id));
Qiang Xu47a567e2018-03-17 01:41:37105 EXPECT_EQ(gfx::Rect(360, 32, 1, 328), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28106
107 // Move 2nd display downwards a bit.
robliaodf372032016-03-23 00:42:34108 layout->placement_list[0].offset = 5;
rjkroege980ccfd2016-10-06 18:00:24109 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28110 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
111 // This is same as before because the 2nd display's y is above
112 // the indicator's x.
oshima77570cb2016-03-24 21:33:23113 ASSERT_EQ(1U, GetWarpRegionsCount());
Qiang Xu47a567e2018-03-17 01:41:37114 EXPECT_EQ(gfx::Rect(359, 32, 1, 328), GetIndicatorBounds(display_0_id));
oshima77570cb2016-03-24 21:33:23115 EXPECT_EQ(gfx::Rect(360, 5, 1, 355), GetIndicatorBounds(display_1_id));
116
oshima83e6f6f2015-04-24 00:30:28117 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23118 EXPECT_EQ(gfx::Rect(359, 5, 1, 355), GetIndicatorBounds(display_0_id));
Qiang Xu47a567e2018-03-17 01:41:37119 EXPECT_EQ(gfx::Rect(360, 37, 1, 323), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28120
121 // Move it down further so that the shared edge is shorter than
122 // minimum hole size (160).
robliaodf372032016-03-23 00:42:34123 layout->placement_list[0].offset = 200;
rjkroege980ccfd2016-10-06 18:00:24124 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28125 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23126 ASSERT_EQ(1U, GetWarpRegionsCount());
127 EXPECT_EQ(gfx::Rect(359, 200, 1, 160), GetIndicatorBounds(display_0_id));
128 EXPECT_EQ(gfx::Rect(360, 200, 1, 160), GetIndicatorBounds(display_1_id));
129
oshima83e6f6f2015-04-24 00:30:28130 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23131 ASSERT_EQ(1U, GetWarpRegionsCount());
132 EXPECT_EQ(gfx::Rect(359, 200, 1, 160), GetIndicatorBounds(display_0_id));
133 EXPECT_EQ(gfx::Rect(360, 200, 1, 160), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28134
Qiang Xu47a567e2018-03-17 01:41:37135 // Now move 2nd display upwards.
robliaodf372032016-03-23 00:42:34136 layout->placement_list[0].offset = -5;
rjkroege980ccfd2016-10-06 18:00:24137 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28138 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23139 ASSERT_EQ(1U, GetWarpRegionsCount());
Qiang Xu47a567e2018-03-17 01:41:37140 EXPECT_EQ(gfx::Rect(359, 32, 1, 328), GetIndicatorBounds(display_0_id));
oshima77570cb2016-03-24 21:33:23141 EXPECT_EQ(gfx::Rect(360, 0, 1, 360), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28142 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
Qiang Xu47a567e2018-03-17 01:41:37143 // 32 px are reserved on 2nd display from top, so y must be
144 // (32 - 5) = 27.
oshima77570cb2016-03-24 21:33:23145 ASSERT_EQ(1U, GetWarpRegionsCount());
146 EXPECT_EQ(gfx::Rect(359, 0, 1, 360), GetIndicatorBounds(display_0_id));
Qiang Xu47a567e2018-03-17 01:41:37147 EXPECT_EQ(gfx::Rect(360, 27, 1, 333), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28148
149 event_filter()->HideSharedEdgeIndicator();
150}
151
152TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnLeft) {
oshima83e6f6f2015-04-24 00:30:28153 UpdateDisplay("360x360,700x700");
154 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
155
oshimaf84b0da722016-04-27 19:47:19156 int64_t display_0_id = display::Screen::GetScreen()
157 ->GetDisplayNearestWindow(root_windows[0])
158 .id();
159 int64_t display_1_id = display::Screen::GetScreen()
160 ->GetDisplayNearestWindow(root_windows[1])
161 .id();
oshima77570cb2016-03-24 21:33:23162
rjkroege72f8154f2016-10-29 00:49:02163 std::unique_ptr<display::DisplayLayout> layout(
164 display::test::CreateDisplayLayout(display_manager(),
165 display::DisplayPlacement::LEFT, 0));
rjkroege980ccfd2016-10-06 18:00:24166 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima77570cb2016-03-24 21:33:23167
oshima83e6f6f2015-04-24 00:30:28168 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23169 ASSERT_EQ(1U, GetWarpRegionsCount());
Qiang Xu47a567e2018-03-17 01:41:37170 EXPECT_EQ(gfx::Rect(0, 32, 1, 328), GetIndicatorBounds(display_0_id));
oshima77570cb2016-03-24 21:33:23171 EXPECT_EQ(gfx::Rect(-1, 0, 1, 360), GetIndicatorBounds(display_1_id));
172
oshima83e6f6f2015-04-24 00:30:28173 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23174 ASSERT_EQ(1U, GetWarpRegionsCount());
175 EXPECT_EQ(gfx::Rect(0, 0, 1, 360), GetIndicatorBounds(display_0_id));
Qiang Xu47a567e2018-03-17 01:41:37176 EXPECT_EQ(gfx::Rect(-1, 32, 1, 328), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28177
robliaodf372032016-03-23 00:42:34178 layout->placement_list[0].offset = 250;
rjkroege980ccfd2016-10-06 18:00:24179 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28180 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23181 ASSERT_EQ(1U, GetWarpRegionsCount());
182 EXPECT_EQ(gfx::Rect(0, 250, 1, 110), GetIndicatorBounds(display_0_id));
183 EXPECT_EQ(gfx::Rect(-1, 250, 1, 110), GetIndicatorBounds(display_1_id));
184
oshima83e6f6f2015-04-24 00:30:28185 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23186 ASSERT_EQ(1U, GetWarpRegionsCount());
187 EXPECT_EQ(gfx::Rect(0, 250, 1, 110), GetIndicatorBounds(display_0_id));
188 EXPECT_EQ(gfx::Rect(-1, 250, 1, 110), GetIndicatorBounds(display_1_id));
189
oshima83e6f6f2015-04-24 00:30:28190 event_filter()->HideSharedEdgeIndicator();
191}
192
193TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnTopBottom) {
oshima83e6f6f2015-04-24 00:30:28194 UpdateDisplay("360x360,700x700");
195 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
oshimaf84b0da722016-04-27 19:47:19196 int64_t display_0_id = display::Screen::GetScreen()
197 ->GetDisplayNearestWindow(root_windows[0])
198 .id();
199 int64_t display_1_id = display::Screen::GetScreen()
200 ->GetDisplayNearestWindow(root_windows[1])
201 .id();
oshima83e6f6f2015-04-24 00:30:28202
rjkroege72f8154f2016-10-29 00:49:02203 std::unique_ptr<display::DisplayLayout> layout(
204 display::test::CreateDisplayLayout(display_manager(),
205 display::DisplayPlacement::TOP, 0));
rjkroege980ccfd2016-10-06 18:00:24206 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28207 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23208 ASSERT_EQ(1U, GetWarpRegionsCount());
209 EXPECT_EQ(gfx::Rect(0, 0, 360, 1), GetIndicatorBounds(display_0_id));
210 EXPECT_EQ(gfx::Rect(0, -1, 360, 1), GetIndicatorBounds(display_1_id));
211
oshima83e6f6f2015-04-24 00:30:28212 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23213 ASSERT_EQ(1U, GetWarpRegionsCount());
214 EXPECT_EQ(gfx::Rect(0, 0, 360, 1), GetIndicatorBounds(display_0_id));
215 EXPECT_EQ(gfx::Rect(0, -1, 360, 1), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28216
robliaodf372032016-03-23 00:42:34217 layout->placement_list[0].offset = 250;
rjkroege980ccfd2016-10-06 18:00:24218 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28219 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23220 ASSERT_EQ(1U, GetWarpRegionsCount());
221 EXPECT_EQ(gfx::Rect(250, 0, 110, 1), GetIndicatorBounds(display_0_id));
222 EXPECT_EQ(gfx::Rect(250, -1, 110, 1), GetIndicatorBounds(display_1_id));
223
oshima83e6f6f2015-04-24 00:30:28224 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23225 ASSERT_EQ(1U, GetWarpRegionsCount());
226 EXPECT_EQ(gfx::Rect(250, 0, 110, 1), GetIndicatorBounds(display_0_id));
227 EXPECT_EQ(gfx::Rect(250, -1, 110, 1), GetIndicatorBounds(display_1_id));
oshima83e6f6f2015-04-24 00:30:28228
robliaoc0dfd6b2016-04-07 21:33:56229 layout->placement_list[0].position = display::DisplayPlacement::BOTTOM;
robliaodf372032016-03-23 00:42:34230 layout->placement_list[0].offset = 0;
rjkroege980ccfd2016-10-06 18:00:24231 display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
oshima83e6f6f2015-04-24 00:30:28232 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
oshima77570cb2016-03-24 21:33:23233 ASSERT_EQ(1U, GetWarpRegionsCount());
234 EXPECT_EQ(gfx::Rect(0, 359, 360, 1), GetIndicatorBounds(display_0_id));
235 EXPECT_EQ(gfx::Rect(0, 360, 360, 1), GetIndicatorBounds(display_1_id));
236
oshima83e6f6f2015-04-24 00:30:28237 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
oshima77570cb2016-03-24 21:33:23238 ASSERT_EQ(1U, GetWarpRegionsCount());
239 EXPECT_EQ(gfx::Rect(0, 359, 360, 1), GetIndicatorBounds(display_0_id));
240 EXPECT_EQ(gfx::Rect(0, 360, 360, 1), GetIndicatorBounds(display_1_id));
jdufaultfb0a42122016-01-21 21:40:41241
242 event_filter()->HideSharedEdgeIndicator();
243}
244
245// Verify indicators show up as expected with 3+ displays.
246TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestThreeDisplays) {
jdufaultfb0a42122016-01-21 21:40:41247 UpdateDisplay("360x360,700x700,1000x1000");
oshima77570cb2016-03-24 21:33:23248 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
oshimaf84b0da722016-04-27 19:47:19249 display::Screen* screen = display::Screen::GetScreen();
oshima77570cb2016-03-24 21:33:23250 int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id();
251 int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id();
252 int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id();
jdufaultfb0a42122016-01-21 21:40:41253
oshima77570cb2016-03-24 21:33:23254 // Drag from left most display
255 event_filter()->ShowSharedEdgeIndicator(root_windows[0]);
256 ASSERT_EQ(2U, GetWarpRegionsCount());
257 const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0);
258 const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1);
Qiang Xu47a567e2018-03-17 01:41:37259 EXPECT_EQ(gfx::Rect(359, 32, 1, 328),
oshima77570cb2016-03-24 21:33:23260 region_1->GetIndicatorBoundsForTest(display_0_id));
261 EXPECT_EQ(gfx::Rect(360, 0, 1, 360),
262 region_1->GetIndicatorBoundsForTest(display_1_id));
263 EXPECT_EQ(gfx::Rect(1059, 0, 1, 700),
264 region_0->GetIndicatorBoundsForTest(display_1_id));
265 EXPECT_EQ(gfx::Rect(1060, 0, 1, 700),
266 region_0->GetIndicatorBoundsForTest(display_2_id));
267
268 // Drag from middle display
269 event_filter()->ShowSharedEdgeIndicator(root_windows[1]);
270 ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size());
271 region_0 = GetWarpRegion(0);
272 region_1 = GetWarpRegion(1);
273 EXPECT_EQ(gfx::Rect(359, 0, 1, 360),
274 region_1->GetIndicatorBoundsForTest(display_0_id));
Qiang Xu47a567e2018-03-17 01:41:37275 EXPECT_EQ(gfx::Rect(360, 32, 1, 328),
oshima77570cb2016-03-24 21:33:23276 region_1->GetIndicatorBoundsForTest(display_1_id));
Qiang Xu47a567e2018-03-17 01:41:37277 EXPECT_EQ(gfx::Rect(1059, 32, 1, 668),
oshima77570cb2016-03-24 21:33:23278 region_0->GetIndicatorBoundsForTest(display_1_id));
279 EXPECT_EQ(gfx::Rect(1060, 0, 1, 700),
280 region_0->GetIndicatorBoundsForTest(display_2_id));
281
282 // Right most display
283 event_filter()->ShowSharedEdgeIndicator(root_windows[2]);
284 ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size());
285 region_0 = GetWarpRegion(0);
286 region_1 = GetWarpRegion(1);
287 EXPECT_EQ(gfx::Rect(359, 0, 1, 360),
288 region_1->GetIndicatorBoundsForTest(display_0_id));
289 EXPECT_EQ(gfx::Rect(360, 0, 1, 360),
290 region_1->GetIndicatorBoundsForTest(display_1_id));
291 EXPECT_EQ(gfx::Rect(1059, 0, 1, 700),
292 region_0->GetIndicatorBoundsForTest(display_1_id));
Qiang Xu47a567e2018-03-17 01:41:37293 EXPECT_EQ(gfx::Rect(1060, 32, 1, 668),
oshima77570cb2016-03-24 21:33:23294 region_0->GetIndicatorBoundsForTest(display_2_id));
295 event_filter()->HideSharedEdgeIndicator();
296 // TODO(oshima): Add test cases primary swap.
297}
298
299TEST_F(ExtendedMouseWarpControllerTest,
300 IndicatorBoundsTestThreeDisplaysWithLayout) {
oshima77570cb2016-03-24 21:33:23301 UpdateDisplay("700x500,500x500,1000x1000");
302 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
oshimaf84b0da722016-04-27 19:47:19303 display::Screen* screen = display::Screen::GetScreen();
oshima77570cb2016-03-24 21:33:23304 int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id();
305 int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id();
306 int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id();
307
308 // Layout so that all displays touches togter like this:
309 // +-----+---+
310 // | 0 | 1 |
311 // +-+---+--++
312 // | 2 |
313 // +------+
robliaoc0dfd6b2016-04-07 21:33:56314 display::DisplayLayoutBuilder builder(display_0_id);
oshima77570cb2016-03-24 21:33:23315 builder.AddDisplayPlacement(display_1_id, display_0_id,
robliaoc0dfd6b2016-04-07 21:33:56316 display::DisplayPlacement::RIGHT, 0);
oshima77570cb2016-03-24 21:33:23317 builder.AddDisplayPlacement(display_2_id, display_0_id,
robliaoc0dfd6b2016-04-07 21:33:56318 display::DisplayPlacement::BOTTOM, 100);
oshima77570cb2016-03-24 21:33:23319
rjkroege980ccfd2016-10-06 18:00:24320 display_manager()->SetLayoutForCurrentDisplays(builder.Build());
oshima77570cb2016-03-24 21:33:23321 ASSERT_EQ(3U, GetWarpRegionsCount());
322
323 // Drag from 0.
324 event_filter()->ShowSharedEdgeIndicator(root_windows[0]);
325 ASSERT_EQ(3U, GetWarpRegionsCount());
326 const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0);
327 const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1);
328 const ExtendedMouseWarpController::WarpRegion* region_2 = GetWarpRegion(2);
329 // between 2 and 0
330 EXPECT_EQ(gfx::Rect(100, 499, 600, 1),
331 region_0->GetIndicatorBoundsForTest(display_0_id));
332 EXPECT_EQ(gfx::Rect(100, 500, 600, 1),
333 region_0->GetIndicatorBoundsForTest(display_2_id));
334 // between 2 and 1
335 EXPECT_EQ(gfx::Rect(700, 499, 400, 1),
336 region_1->GetIndicatorBoundsForTest(display_1_id));
337 EXPECT_EQ(gfx::Rect(700, 500, 400, 1),
338 region_1->GetIndicatorBoundsForTest(display_2_id));
339 // between 1 and 0
Qiang Xu47a567e2018-03-17 01:41:37340 EXPECT_EQ(gfx::Rect(699, 32, 1, 468),
oshima77570cb2016-03-24 21:33:23341 region_2->GetIndicatorBoundsForTest(display_0_id));
342 EXPECT_EQ(gfx::Rect(700, 0, 1, 500),
343 region_2->GetIndicatorBoundsForTest(display_1_id));
344 event_filter()->HideSharedEdgeIndicator();
345}
346
347TEST_F(ExtendedMouseWarpControllerTest,
348 IndicatorBoundsTestThreeDisplaysWithLayout2) {
oshima77570cb2016-03-24 21:33:23349 UpdateDisplay("700x500,500x500,1000x1000");
350 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
oshimaf84b0da722016-04-27 19:47:19351 display::Screen* screen = display::Screen::GetScreen();
oshima77570cb2016-03-24 21:33:23352 int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id();
353 int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id();
354 int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id();
355
356 // Layout so that 0 and 1 displays are disconnected.
357 // +-----+ +---+
358 // | 0 | |1 |
359 // +-+---+-+++
360 // | 2 |
361 // +------+
robliaoc0dfd6b2016-04-07 21:33:56362 display::DisplayLayoutBuilder builder(display_0_id);
oshima77570cb2016-03-24 21:33:23363 builder.AddDisplayPlacement(display_2_id, display_0_id,
robliaoc0dfd6b2016-04-07 21:33:56364 display::DisplayPlacement::BOTTOM, 100);
oshima77570cb2016-03-24 21:33:23365 builder.AddDisplayPlacement(display_1_id, display_2_id,
robliaoc0dfd6b2016-04-07 21:33:56366 display::DisplayPlacement::TOP, 800);
oshima77570cb2016-03-24 21:33:23367
rjkroege980ccfd2016-10-06 18:00:24368 display_manager()->SetLayoutForCurrentDisplays(builder.Build());
oshima77570cb2016-03-24 21:33:23369 ASSERT_EQ(2U, GetWarpRegionsCount());
370
371 // Drag from 0.
372 event_filter()->ShowSharedEdgeIndicator(root_windows[0]);
373 ASSERT_EQ(2U, GetWarpRegionsCount());
374 const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0);
375 const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1);
376 // between 2 and 0
377 EXPECT_EQ(gfx::Rect(100, 499, 600, 1),
378 region_0->GetIndicatorBoundsForTest(display_0_id));
379 EXPECT_EQ(gfx::Rect(100, 500, 600, 1),
380 region_0->GetIndicatorBoundsForTest(display_2_id));
381 // between 2 and 1
382 EXPECT_EQ(gfx::Rect(900, 499, 200, 1),
383 region_1->GetIndicatorBoundsForTest(display_1_id));
384 EXPECT_EQ(gfx::Rect(900, 500, 200, 1),
385 region_1->GetIndicatorBoundsForTest(display_2_id));
386 event_filter()->HideSharedEdgeIndicator();
oshima83e6f6f2015-04-24 00:30:28387}
388
Andrew Xua6cdb0f02018-12-06 17:56:38389// Check that the point in the rotated secondary display's warp region is
390// converted correctly from native host coordinates to screen DIP coordinates.
391// (see https://crbug.com/905035)
392TEST_F(ExtendedMouseWarpControllerTest,
393 CheckHostPointToScreenInMouseWarpRegion) {
394 // Zoom factor is needed to trigger rounding error which occured in previous
395 // code.
396 UpdateDisplay("[email protected],50+300-300x100/r");
397
398 aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
399
400 // Check the primary display's size and scale.
401 display::Display primary_display =
402 display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]);
403 ASSERT_EQ("250x250", primary_display.size().ToString());
404 ASSERT_EQ(0.8f, primary_display.device_scale_factor());
405
406 // Create a window to be dragged in primary display.
407 std::unique_ptr<aura::test::TestWindowDelegate> test_window_delegate =
408 std::make_unique<aura::test::TestWindowDelegate>();
409 test_window_delegate->set_window_component(HTCAPTION);
410 const gfx::Size initial_window_size(100, 100);
411 std::unique_ptr<aura::Window> test_window(
412 CreateTestWindowInShellWithDelegateAndType(
413 test_window_delegate.get(), aura::client::WINDOW_TYPE_NORMAL, 0,
414 gfx::Rect(initial_window_size)));
415 ASSERT_EQ(root_windows[0], test_window->GetRootWindow());
416 ASSERT_FALSE(test_window->HasCapture());
417
418 AshWindowTreeHostPlatform* window_host =
419 static_cast<AshWindowTreeHostPlatform*>(root_windows[0]->GetHost());
420
421 // Move mouse cursor and capture the window.
422 gfx::Point location_in_host_native(0, 0);
423 DispatchMouseEventWithNative(window_host, location_in_host_native,
424 ui::ET_MOUSE_MOVED, ui::EF_NONE, ui::EF_NONE);
425 DispatchMouseEventWithNative(window_host, location_in_host_native,
426 ui::ET_MOUSE_PRESSED, ui::EF_LEFT_MOUSE_BUTTON,
427 ui::EF_LEFT_MOUSE_BUTTON);
428
429 // Window should be captured.
430 ASSERT_TRUE(test_window->HasCapture());
431
432 int64_t display_0_id = primary_display.id();
433 const gfx::Rect indicator_in_primary_display =
434 GetIndicatorNativeBounds(display_0_id);
435 int64_t display_1_id = display::Screen::GetScreen()
436 ->GetDisplayNearestWindow(root_windows[1])
437 .id();
438 const gfx::Rect indicator_in_secondary_display =
439 GetIndicatorNativeBounds(display_1_id);
440
441 gfx::Point location_in_screen_native, location_in_screen_dip;
442
443 // Move mouse cursor to the warp region of first display.
444 location_in_screen_native = indicator_in_primary_display.CenterPoint();
445 location_in_host_native =
446 location_in_screen_native -
447 root_windows[0]->GetHost()->GetBoundsInPixels().OffsetFromOrigin();
448 DispatchMouseEventWithNative(window_host, location_in_host_native,
449 ui::ET_MOUSE_DRAGGED, ui::EF_LEFT_MOUSE_BUTTON,
450 0);
451
452 // Mouse cursor should be warped into secondary display.
453 location_in_screen_dip = Shell::Get()->aura_env()->last_mouse_location();
454 EXPECT_TRUE(
455 root_windows[1]->GetBoundsInScreen().Contains(location_in_screen_dip));
456
457 // Move mouse cursor to the warp region of secondary display.
458 location_in_screen_native = indicator_in_secondary_display.CenterPoint();
459 location_in_host_native =
460 location_in_screen_native -
461 root_windows[0]->GetHost()->GetBoundsInPixels().OffsetFromOrigin();
462 DispatchMouseEventWithNative(window_host, location_in_host_native,
463 ui::ET_MOUSE_DRAGGED, ui::EF_LEFT_MOUSE_BUTTON,
464 0);
465
466 // Mouse cursor should be warped into first display.
467 location_in_screen_dip = Shell::Get()->aura_env()->last_mouse_location();
468 EXPECT_TRUE(
469 root_windows[0]->GetBoundsInScreen().Contains(location_in_screen_dip));
470
471 // After mouse warping, x-coordinate of mouse location in native coordinates
472 // should be 2 px away from end. Primary display has zoom factor of 0.8. So
473 // the offset in screen coordinates should be 2/0.8, which is 2.5. The end of
474 // primary display in screen coordinates is 250. So x-coordinate of mouse
475 // cursor in screen coordinates should be 247.
476 EXPECT_EQ(247, Shell::Get()->aura_env()->last_mouse_location().x());
477
478 // Get cursor's location in host native coordinates.
479 gfx::Point location_in_host_dip;
480 location_in_screen_dip = Shell::Get()->aura_env()->last_mouse_location();
481 location_in_host_dip = location_in_screen_dip;
482 ::wm::ConvertPointFromScreen(root_windows[0], &location_in_host_dip);
483 location_in_host_native = location_in_host_dip;
484 root_windows[0]->GetHost()->ConvertDIPToPixels(&location_in_host_native);
485
486 // Release mouse button.
487 DispatchMouseEventWithNative(window_host, location_in_host_native,
488 ui::ET_MOUSE_RELEASED, ui::EF_LEFT_MOUSE_BUTTON,
489 ui::EF_LEFT_MOUSE_BUTTON);
490}
491
oshima83e6f6f2015-04-24 00:30:28492} // namespace ash