extended_mouse_warp_controller_unittest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  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.
  4. #include "ash/display/extended_mouse_warp_controller.h"
  5. #include "ash/display/mouse_cursor_event_filter.h"
  6. #include "ash/display/screen_position_controller.h"
  7. #include "ash/host/ash_window_tree_host_platform.h"
  8. #include "ash/shell.h"
  9. #include "ash/test/ash_test_base.h"
  10. #include "ui/aura/env.h"
  11. #include "ui/aura/test/test_windows.h"
  12. #include "ui/aura/window_tree_host.h"
  13. #include "ui/base/hit_test.h"
  14. #include "ui/display/display.h"
  15. #include "ui/display/display_layout.h"
  16. #include "ui/display/display_layout_builder.h"
  17. #include "ui/display/manager/display_manager.h"
  18. #include "ui/display/screen.h"
  19. #include "ui/display/test/display_manager_test_api.h"
  20. #include "ui/events/base_event_utils.h"
  21. #include "ui/events/test/event_generator.h"
  22. #include "ui/wm/core/coordinate_conversion.h"
  23. namespace ash {
  24. class ExtendedMouseWarpControllerTest : public AshTestBase {
  25. public:
  26. ExtendedMouseWarpControllerTest() = default;
  27. ExtendedMouseWarpControllerTest(const ExtendedMouseWarpControllerTest&) =
  28. delete;
  29. ExtendedMouseWarpControllerTest& operator=(
  30. const ExtendedMouseWarpControllerTest&) = delete;
  31. ~ExtendedMouseWarpControllerTest() override = default;
  32. protected:
  33. MouseCursorEventFilter* event_filter() {
  34. return Shell::Get()->mouse_cursor_filter();
  35. }
  36. ExtendedMouseWarpController* mouse_warp_controller() {
  37. return static_cast<ExtendedMouseWarpController*>(
  38. event_filter()->mouse_warp_controller_for_test());
  39. }
  40. size_t GetWarpRegionsCount() {
  41. return mouse_warp_controller()->warp_regions_.size();
  42. }
  43. const ExtendedMouseWarpController::WarpRegion* GetWarpRegion(size_t index) {
  44. return mouse_warp_controller()->warp_regions_[index].get();
  45. }
  46. const gfx::Rect& GetIndicatorBounds(int64_t id) {
  47. return GetWarpRegion(0)->GetIndicatorBoundsForTest(id);
  48. }
  49. const gfx::Rect& GetIndicatorNativeBounds(int64_t id) {
  50. return GetWarpRegion(0)->GetIndicatorNativeBoundsForTest(id);
  51. }
  52. // Send mouse event with native event through AshWindowTreeHostPlatform.
  53. void DispatchMouseEventWithNative(AshWindowTreeHostPlatform* host,
  54. const gfx::Point& location_in_host_native,
  55. ui::EventType event_type,
  56. int event_flag1,
  57. int event_flag2) {
  58. ui::MouseEvent native_event(event_type, location_in_host_native,
  59. location_in_host_native, ui::EventTimeForNow(),
  60. event_flag1, event_flag2);
  61. ui::MouseEvent mouseev(&native_event);
  62. host->DispatchEvent(&mouseev);
  63. // The test relies on the last_mouse_location, which will be updated by
  64. // a synthesized event posted asynchronusly. Wait until the synthesized
  65. // event is handled and last mouse location is updated.
  66. base::RunLoop().RunUntilIdle();
  67. }
  68. };
  69. // Verifies if MouseCursorEventFilter's bounds calculation works correctly.
  70. TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnRight) {
  71. UpdateDisplay("360x350,800x700");
  72. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  73. int64_t display_0_id = display::Screen::GetScreen()
  74. ->GetDisplayNearestWindow(root_windows[0])
  75. .id();
  76. int64_t display_1_id = display::Screen::GetScreen()
  77. ->GetDisplayNearestWindow(root_windows[1])
  78. .id();
  79. std::unique_ptr<display::DisplayLayout> layout(
  80. display::test::CreateDisplayLayout(display_manager(),
  81. display::DisplayPlacement::RIGHT, 0));
  82. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  83. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  84. ASSERT_EQ(1U, GetWarpRegionsCount());
  85. EXPECT_EQ(gfx::Rect(359, 32, 1, 318), GetIndicatorBounds(display_0_id));
  86. EXPECT_EQ(gfx::Rect(360, 0, 1, 350), GetIndicatorBounds(display_1_id));
  87. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  88. EXPECT_EQ(gfx::Rect(359, 0, 1, 350), GetIndicatorBounds(display_0_id));
  89. EXPECT_EQ(gfx::Rect(360, 32, 1, 318), GetIndicatorBounds(display_1_id));
  90. // Move 2nd display downwards a bit.
  91. layout->placement_list[0].offset = 5;
  92. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  93. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  94. // This is same as before because the 2nd display's y is above
  95. // the indicator's x.
  96. ASSERT_EQ(1U, GetWarpRegionsCount());
  97. EXPECT_EQ(gfx::Rect(359, 32, 1, 318), GetIndicatorBounds(display_0_id));
  98. EXPECT_EQ(gfx::Rect(360, 5, 1, 345), GetIndicatorBounds(display_1_id));
  99. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  100. EXPECT_EQ(gfx::Rect(359, 5, 1, 345), GetIndicatorBounds(display_0_id));
  101. EXPECT_EQ(gfx::Rect(360, 37, 1, 313), GetIndicatorBounds(display_1_id));
  102. // Move it down further so that the shared edge is shorter than
  103. // minimum hole size (160).
  104. layout->placement_list[0].offset = 200;
  105. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  106. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  107. ASSERT_EQ(1U, GetWarpRegionsCount());
  108. EXPECT_EQ(gfx::Rect(359, 200, 1, 150), GetIndicatorBounds(display_0_id));
  109. EXPECT_EQ(gfx::Rect(360, 200, 1, 150), GetIndicatorBounds(display_1_id));
  110. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  111. ASSERT_EQ(1U, GetWarpRegionsCount());
  112. EXPECT_EQ(gfx::Rect(359, 200, 1, 150), GetIndicatorBounds(display_0_id));
  113. EXPECT_EQ(gfx::Rect(360, 200, 1, 150), GetIndicatorBounds(display_1_id));
  114. // Now move 2nd display upwards.
  115. layout->placement_list[0].offset = -5;
  116. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  117. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  118. ASSERT_EQ(1U, GetWarpRegionsCount());
  119. EXPECT_EQ(gfx::Rect(359, 32, 1, 318), GetIndicatorBounds(display_0_id));
  120. EXPECT_EQ(gfx::Rect(360, 0, 1, 350), GetIndicatorBounds(display_1_id));
  121. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  122. // 32 px are reserved on 2nd display from top, so y must be
  123. // (32 - 5) = 27.
  124. ASSERT_EQ(1U, GetWarpRegionsCount());
  125. EXPECT_EQ(gfx::Rect(359, 0, 1, 350), GetIndicatorBounds(display_0_id));
  126. EXPECT_EQ(gfx::Rect(360, 27, 1, 323), GetIndicatorBounds(display_1_id));
  127. event_filter()->HideSharedEdgeIndicator();
  128. }
  129. TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnLeft) {
  130. UpdateDisplay("360x350,800x700");
  131. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  132. int64_t display_0_id = display::Screen::GetScreen()
  133. ->GetDisplayNearestWindow(root_windows[0])
  134. .id();
  135. int64_t display_1_id = display::Screen::GetScreen()
  136. ->GetDisplayNearestWindow(root_windows[1])
  137. .id();
  138. std::unique_ptr<display::DisplayLayout> layout(
  139. display::test::CreateDisplayLayout(display_manager(),
  140. display::DisplayPlacement::LEFT, 0));
  141. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  142. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  143. ASSERT_EQ(1U, GetWarpRegionsCount());
  144. EXPECT_EQ(gfx::Rect(0, 32, 1, 318), GetIndicatorBounds(display_0_id));
  145. EXPECT_EQ(gfx::Rect(-1, 0, 1, 350), GetIndicatorBounds(display_1_id));
  146. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  147. ASSERT_EQ(1U, GetWarpRegionsCount());
  148. EXPECT_EQ(gfx::Rect(0, 0, 1, 350), GetIndicatorBounds(display_0_id));
  149. EXPECT_EQ(gfx::Rect(-1, 32, 1, 318), GetIndicatorBounds(display_1_id));
  150. layout->placement_list[0].offset = 250;
  151. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  152. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  153. ASSERT_EQ(1U, GetWarpRegionsCount());
  154. EXPECT_EQ(gfx::Rect(0, 250, 1, 100), GetIndicatorBounds(display_0_id));
  155. EXPECT_EQ(gfx::Rect(-1, 250, 1, 100), GetIndicatorBounds(display_1_id));
  156. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  157. ASSERT_EQ(1U, GetWarpRegionsCount());
  158. EXPECT_EQ(gfx::Rect(0, 250, 1, 100), GetIndicatorBounds(display_0_id));
  159. EXPECT_EQ(gfx::Rect(-1, 250, 1, 100), GetIndicatorBounds(display_1_id));
  160. event_filter()->HideSharedEdgeIndicator();
  161. }
  162. TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestOnTopBottom) {
  163. UpdateDisplay("360x350,800x700");
  164. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  165. int64_t display_0_id = display::Screen::GetScreen()
  166. ->GetDisplayNearestWindow(root_windows[0])
  167. .id();
  168. int64_t display_1_id = display::Screen::GetScreen()
  169. ->GetDisplayNearestWindow(root_windows[1])
  170. .id();
  171. std::unique_ptr<display::DisplayLayout> layout(
  172. display::test::CreateDisplayLayout(display_manager(),
  173. display::DisplayPlacement::TOP, 0));
  174. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  175. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  176. ASSERT_EQ(1U, GetWarpRegionsCount());
  177. EXPECT_EQ(gfx::Rect(0, 0, 360, 1), GetIndicatorBounds(display_0_id));
  178. EXPECT_EQ(gfx::Rect(0, -1, 360, 1), GetIndicatorBounds(display_1_id));
  179. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  180. ASSERT_EQ(1U, GetWarpRegionsCount());
  181. EXPECT_EQ(gfx::Rect(0, 0, 360, 1), GetIndicatorBounds(display_0_id));
  182. EXPECT_EQ(gfx::Rect(0, -1, 360, 1), GetIndicatorBounds(display_1_id));
  183. layout->placement_list[0].offset = 250;
  184. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  185. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  186. ASSERT_EQ(1U, GetWarpRegionsCount());
  187. EXPECT_EQ(gfx::Rect(250, 0, 110, 1), GetIndicatorBounds(display_0_id));
  188. EXPECT_EQ(gfx::Rect(250, -1, 110, 1), GetIndicatorBounds(display_1_id));
  189. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  190. ASSERT_EQ(1U, GetWarpRegionsCount());
  191. EXPECT_EQ(gfx::Rect(250, 0, 110, 1), GetIndicatorBounds(display_0_id));
  192. EXPECT_EQ(gfx::Rect(250, -1, 110, 1), GetIndicatorBounds(display_1_id));
  193. layout->placement_list[0].position = display::DisplayPlacement::BOTTOM;
  194. layout->placement_list[0].offset = 0;
  195. display_manager()->SetLayoutForCurrentDisplays(layout->Copy());
  196. event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
  197. ASSERT_EQ(1U, GetWarpRegionsCount());
  198. EXPECT_EQ(gfx::Rect(0, 349, 360, 1), GetIndicatorBounds(display_0_id));
  199. EXPECT_EQ(gfx::Rect(0, 350, 360, 1), GetIndicatorBounds(display_1_id));
  200. event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
  201. ASSERT_EQ(1U, GetWarpRegionsCount());
  202. EXPECT_EQ(gfx::Rect(0, 349, 360, 1), GetIndicatorBounds(display_0_id));
  203. EXPECT_EQ(gfx::Rect(0, 350, 360, 1), GetIndicatorBounds(display_1_id));
  204. event_filter()->HideSharedEdgeIndicator();
  205. }
  206. // Verify indicators show up as expected with 3+ displays.
  207. TEST_F(ExtendedMouseWarpControllerTest, IndicatorBoundsTestThreeDisplays) {
  208. UpdateDisplay("360x350,800x700,1000x900");
  209. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  210. display::Screen* screen = display::Screen::GetScreen();
  211. int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id();
  212. int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id();
  213. int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id();
  214. // Drag from left most display
  215. event_filter()->ShowSharedEdgeIndicator(root_windows[0]);
  216. ASSERT_EQ(2U, GetWarpRegionsCount());
  217. const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0);
  218. const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1);
  219. EXPECT_EQ(gfx::Rect(359, 32, 1, 318),
  220. region_1->GetIndicatorBoundsForTest(display_0_id));
  221. EXPECT_EQ(gfx::Rect(360, 0, 1, 350),
  222. region_1->GetIndicatorBoundsForTest(display_1_id));
  223. EXPECT_EQ(gfx::Rect(1159, 0, 1, 700),
  224. region_0->GetIndicatorBoundsForTest(display_1_id));
  225. EXPECT_EQ(gfx::Rect(1160, 0, 1, 700),
  226. region_0->GetIndicatorBoundsForTest(display_2_id));
  227. // Drag from middle display
  228. event_filter()->ShowSharedEdgeIndicator(root_windows[1]);
  229. ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size());
  230. region_0 = GetWarpRegion(0);
  231. region_1 = GetWarpRegion(1);
  232. EXPECT_EQ(gfx::Rect(359, 0, 1, 350),
  233. region_1->GetIndicatorBoundsForTest(display_0_id));
  234. EXPECT_EQ(gfx::Rect(360, 32, 1, 318),
  235. region_1->GetIndicatorBoundsForTest(display_1_id));
  236. EXPECT_EQ(gfx::Rect(1159, 32, 1, 668),
  237. region_0->GetIndicatorBoundsForTest(display_1_id));
  238. EXPECT_EQ(gfx::Rect(1160, 0, 1, 700),
  239. region_0->GetIndicatorBoundsForTest(display_2_id));
  240. // Right most display
  241. event_filter()->ShowSharedEdgeIndicator(root_windows[2]);
  242. ASSERT_EQ(2U, mouse_warp_controller()->warp_regions_.size());
  243. region_0 = GetWarpRegion(0);
  244. region_1 = GetWarpRegion(1);
  245. EXPECT_EQ(gfx::Rect(359, 0, 1, 350),
  246. region_1->GetIndicatorBoundsForTest(display_0_id));
  247. EXPECT_EQ(gfx::Rect(360, 0, 1, 350),
  248. region_1->GetIndicatorBoundsForTest(display_1_id));
  249. EXPECT_EQ(gfx::Rect(1159, 0, 1, 700),
  250. region_0->GetIndicatorBoundsForTest(display_1_id));
  251. EXPECT_EQ(gfx::Rect(1160, 32, 1, 668),
  252. region_0->GetIndicatorBoundsForTest(display_2_id));
  253. event_filter()->HideSharedEdgeIndicator();
  254. // TODO(oshima): Add test cases primary swap.
  255. }
  256. TEST_F(ExtendedMouseWarpControllerTest,
  257. IndicatorBoundsTestThreeDisplaysWithLayout) {
  258. UpdateDisplay("700x500,600x500,1000x900");
  259. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  260. display::Screen* screen = display::Screen::GetScreen();
  261. int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id();
  262. int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id();
  263. int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id();
  264. // Layout so that all displays touches togter like this:
  265. // +-----+---+
  266. // | 0 | 1 |
  267. // +-+---+--++
  268. // | 2 |
  269. // +------+
  270. display::DisplayLayoutBuilder builder(display_0_id);
  271. builder.AddDisplayPlacement(display_1_id, display_0_id,
  272. display::DisplayPlacement::RIGHT, 0);
  273. builder.AddDisplayPlacement(display_2_id, display_0_id,
  274. display::DisplayPlacement::BOTTOM, 100);
  275. display_manager()->SetLayoutForCurrentDisplays(builder.Build());
  276. ASSERT_EQ(3U, GetWarpRegionsCount());
  277. // Drag from 0.
  278. event_filter()->ShowSharedEdgeIndicator(root_windows[0]);
  279. ASSERT_EQ(3U, GetWarpRegionsCount());
  280. const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0);
  281. const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1);
  282. const ExtendedMouseWarpController::WarpRegion* region_2 = GetWarpRegion(2);
  283. // between 2 and 0
  284. EXPECT_EQ(gfx::Rect(100, 499, 600, 1),
  285. region_0->GetIndicatorBoundsForTest(display_0_id));
  286. EXPECT_EQ(gfx::Rect(100, 500, 600, 1),
  287. region_0->GetIndicatorBoundsForTest(display_2_id));
  288. // between 2 and 1
  289. EXPECT_EQ(gfx::Rect(700, 499, 400, 1),
  290. region_1->GetIndicatorBoundsForTest(display_1_id));
  291. EXPECT_EQ(gfx::Rect(700, 500, 400, 1),
  292. region_1->GetIndicatorBoundsForTest(display_2_id));
  293. // between 1 and 0
  294. EXPECT_EQ(gfx::Rect(699, 32, 1, 468),
  295. region_2->GetIndicatorBoundsForTest(display_0_id));
  296. EXPECT_EQ(gfx::Rect(700, 0, 1, 500),
  297. region_2->GetIndicatorBoundsForTest(display_1_id));
  298. event_filter()->HideSharedEdgeIndicator();
  299. }
  300. TEST_F(ExtendedMouseWarpControllerTest,
  301. IndicatorBoundsTestThreeDisplaysWithLayout2) {
  302. UpdateDisplay("700x500,600x500,1000x900");
  303. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  304. display::Screen* screen = display::Screen::GetScreen();
  305. int64_t display_0_id = screen->GetDisplayNearestWindow(root_windows[0]).id();
  306. int64_t display_1_id = screen->GetDisplayNearestWindow(root_windows[1]).id();
  307. int64_t display_2_id = screen->GetDisplayNearestWindow(root_windows[2]).id();
  308. // Layout so that 0 and 1 displays are disconnected.
  309. // +-----+ +---+
  310. // | 0 | |1 |
  311. // +-+---+-+++
  312. // | 2 |
  313. // +------+
  314. display::DisplayLayoutBuilder builder(display_0_id);
  315. builder.AddDisplayPlacement(display_2_id, display_0_id,
  316. display::DisplayPlacement::BOTTOM, 100);
  317. builder.AddDisplayPlacement(display_1_id, display_2_id,
  318. display::DisplayPlacement::TOP, 800);
  319. display_manager()->SetLayoutForCurrentDisplays(builder.Build());
  320. ASSERT_EQ(2U, GetWarpRegionsCount());
  321. // Drag from 0.
  322. event_filter()->ShowSharedEdgeIndicator(root_windows[0]);
  323. ASSERT_EQ(2U, GetWarpRegionsCount());
  324. const ExtendedMouseWarpController::WarpRegion* region_0 = GetWarpRegion(0);
  325. const ExtendedMouseWarpController::WarpRegion* region_1 = GetWarpRegion(1);
  326. // between 2 and 0
  327. EXPECT_EQ(gfx::Rect(100, 499, 600, 1),
  328. region_0->GetIndicatorBoundsForTest(display_0_id));
  329. EXPECT_EQ(gfx::Rect(100, 500, 600, 1),
  330. region_0->GetIndicatorBoundsForTest(display_2_id));
  331. // between 2 and 1
  332. EXPECT_EQ(gfx::Rect(900, 499, 200, 1),
  333. region_1->GetIndicatorBoundsForTest(display_1_id));
  334. EXPECT_EQ(gfx::Rect(900, 500, 200, 1),
  335. region_1->GetIndicatorBoundsForTest(display_2_id));
  336. event_filter()->HideSharedEdgeIndicator();
  337. }
  338. // Check that the point in the rotated secondary display's warp region is
  339. // converted correctly from native host coordinates to screen DIP coordinates.
  340. // (see https://crbug.com/905035)
  341. // Flaky. https://crbug.com/1217187.
  342. TEST_F(ExtendedMouseWarpControllerTest,
  343. DISABLED_CheckHostPointToScreenInMouseWarpRegion) {
  344. // Zoom factor is needed to trigger rounding error which occured in previous
  345. // code.
  346. UpdateDisplay("50+50-300x200@0.8,50+300-300x100/r");
  347. aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  348. // Check the primary display's size and scale.
  349. display::Display primary_display =
  350. display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]);
  351. ASSERT_EQ("250x250", primary_display.size().ToString());
  352. ASSERT_EQ(0.8f, primary_display.device_scale_factor());
  353. // Create a window to be dragged in primary display.
  354. std::unique_ptr<aura::test::TestWindowDelegate> test_window_delegate =
  355. std::make_unique<aura::test::TestWindowDelegate>();
  356. test_window_delegate->set_window_component(HTCAPTION);
  357. const gfx::Size initial_window_size(100, 100);
  358. std::unique_ptr<aura::Window> test_window(
  359. CreateTestWindowInShellWithDelegateAndType(
  360. test_window_delegate.get(), aura::client::WINDOW_TYPE_NORMAL, 0,
  361. gfx::Rect(initial_window_size)));
  362. ASSERT_EQ(root_windows[0], test_window->GetRootWindow());
  363. ASSERT_FALSE(test_window->HasCapture());
  364. AshWindowTreeHostPlatform* window_host =
  365. static_cast<AshWindowTreeHostPlatform*>(root_windows[0]->GetHost());
  366. // Move mouse cursor and capture the window.
  367. gfx::Point location_in_host_native(0, 0);
  368. DispatchMouseEventWithNative(window_host, location_in_host_native,
  369. ui::ET_MOUSE_MOVED, ui::EF_NONE, ui::EF_NONE);
  370. DispatchMouseEventWithNative(window_host, location_in_host_native,
  371. ui::ET_MOUSE_PRESSED, ui::EF_LEFT_MOUSE_BUTTON,
  372. ui::EF_LEFT_MOUSE_BUTTON);
  373. // Window should be captured.
  374. ASSERT_TRUE(test_window->HasCapture());
  375. int64_t display_0_id = primary_display.id();
  376. const gfx::Rect indicator_in_primary_display =
  377. GetIndicatorNativeBounds(display_0_id);
  378. int64_t display_1_id = display::Screen::GetScreen()
  379. ->GetDisplayNearestWindow(root_windows[1])
  380. .id();
  381. const gfx::Rect indicator_in_secondary_display =
  382. GetIndicatorNativeBounds(display_1_id);
  383. gfx::Point location_in_screen_native, location_in_screen_dip;
  384. // Move mouse cursor to the warp region of first display.
  385. location_in_screen_native = indicator_in_primary_display.CenterPoint();
  386. location_in_host_native =
  387. location_in_screen_native -
  388. root_windows[0]->GetHost()->GetBoundsInPixels().OffsetFromOrigin();
  389. DispatchMouseEventWithNative(window_host, location_in_host_native,
  390. ui::ET_MOUSE_DRAGGED, ui::EF_LEFT_MOUSE_BUTTON,
  391. 0);
  392. // Mouse cursor should be warped into secondary display.
  393. location_in_screen_dip = aura::Env::GetInstance()->last_mouse_location();
  394. EXPECT_TRUE(
  395. root_windows[1]->GetBoundsInScreen().Contains(location_in_screen_dip));
  396. // Move mouse cursor to the warp region of secondary display.
  397. location_in_screen_native = indicator_in_secondary_display.CenterPoint();
  398. location_in_host_native =
  399. location_in_screen_native -
  400. root_windows[0]->GetHost()->GetBoundsInPixels().OffsetFromOrigin();
  401. DispatchMouseEventWithNative(window_host, location_in_host_native,
  402. ui::ET_MOUSE_DRAGGED, ui::EF_LEFT_MOUSE_BUTTON,
  403. 0);
  404. // Mouse cursor should be warped into first display.
  405. location_in_screen_dip = aura::Env::GetInstance()->last_mouse_location();
  406. EXPECT_TRUE(
  407. root_windows[0]->GetBoundsInScreen().Contains(location_in_screen_dip));
  408. // After mouse warping, x-coordinate of mouse location in native coordinates
  409. // should be 2 px away from end. Primary display has zoom factor of 0.8. So
  410. // the offset in screen coordinates should be 2/0.8, which is 2.5. The end of
  411. // primary display in screen coordinates is 250. So x-coordinate of mouse
  412. // cursor in screen coordinates should be 247.
  413. EXPECT_EQ(247, aura::Env::GetInstance()->last_mouse_location().x());
  414. // Get cursor's location in host native coordinates.
  415. gfx::Point location_in_host_dip;
  416. location_in_screen_dip = aura::Env::GetInstance()->last_mouse_location();
  417. location_in_host_dip = location_in_screen_dip;
  418. ::wm::ConvertPointFromScreen(root_windows[0], &location_in_host_dip);
  419. location_in_host_native = location_in_host_dip;
  420. root_windows[0]->GetHost()->ConvertDIPToPixels(&location_in_host_native);
  421. // Release mouse button.
  422. DispatchMouseEventWithNative(window_host, location_in_host_native,
  423. ui::ET_MOUSE_RELEASED, ui::EF_LEFT_MOUSE_BUTTON,
  424. ui::EF_LEFT_MOUSE_BUTTON);
  425. }
  426. } // namespace ash