root_window_transformers_unittest.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. // Copyright 2013 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/root_window_transformers.h"
  5. #include <memory>
  6. #include "ash/accessibility/magnifier/fullscreen_magnifier_controller.h"
  7. #include "ash/display/display_util.h"
  8. #include "ash/display/mirror_window_test_api.h"
  9. #include "ash/host/root_window_transformer.h"
  10. #include "ash/screen_util.h"
  11. #include "ash/shelf/shelf_widget.h"
  12. #include "ash/shell.h"
  13. #include "ash/test/ash_test_base.h"
  14. #include "ash/wm/cursor_manager_test_api.h"
  15. #include "base/synchronization/waitable_event.h"
  16. #include "ui/aura/env.h"
  17. #include "ui/aura/window_event_dispatcher.h"
  18. #include "ui/aura/window_tracker.h"
  19. #include "ui/aura/window_tree_host.h"
  20. #include "ui/compositor/layer.h"
  21. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  22. #include "ui/compositor/scoped_layer_animation_settings.h"
  23. #include "ui/display/display.h"
  24. #include "ui/display/display_layout.h"
  25. #include "ui/display/manager/display_manager.h"
  26. #include "ui/display/manager/managed_display_info.h"
  27. #include "ui/display/screen.h"
  28. #include "ui/display/test/display_manager_test_api.h"
  29. #include "ui/events/event_handler.h"
  30. #include "ui/events/test/event_generator.h"
  31. #include "ui/gfx/geometry/rect_conversions.h"
  32. #include "ui/gfx/geometry/rect_f.h"
  33. #include "ui/views/widget/widget.h"
  34. namespace ash {
  35. namespace {
  36. const char kWallpaperView[] = "WallpaperViewWidget";
  37. class TestEventHandler : public ui::EventHandler {
  38. public:
  39. TestEventHandler()
  40. : target_root_(nullptr),
  41. touch_radius_x_(0.0),
  42. touch_radius_y_(0.0),
  43. scroll_x_offset_(0.0),
  44. scroll_y_offset_(0.0),
  45. scroll_x_offset_ordinal_(0.0),
  46. scroll_y_offset_ordinal_(0.0) {}
  47. TestEventHandler(const TestEventHandler&) = delete;
  48. TestEventHandler& operator=(const TestEventHandler&) = delete;
  49. ~TestEventHandler() override = default;
  50. void OnMouseEvent(ui::MouseEvent* event) override {
  51. if (event->flags() & ui::EF_IS_SYNTHESIZED)
  52. return;
  53. aura::Window* target = static_cast<aura::Window*>(event->target());
  54. mouse_location_ = event->root_location();
  55. target_root_ = target->GetRootWindow();
  56. event->StopPropagation();
  57. }
  58. void OnTouchEvent(ui::TouchEvent* event) override {
  59. aura::Window* target = static_cast<aura::Window*>(event->target());
  60. // Only record when the target is the wallpaper, which covers the entire
  61. // root window.
  62. if (target->GetName() != kWallpaperView)
  63. return;
  64. touch_radius_x_ = event->pointer_details().radius_x;
  65. touch_radius_y_ = event->pointer_details().radius_y;
  66. event->StopPropagation();
  67. }
  68. void OnScrollEvent(ui::ScrollEvent* event) override {
  69. aura::Window* target = static_cast<aura::Window*>(event->target());
  70. // Only record when the target is the wallpaper, which covers the entire
  71. // root window.
  72. if (target->GetName() != kWallpaperView)
  73. return;
  74. if (event->type() == ui::ET_SCROLL) {
  75. scroll_x_offset_ = event->x_offset();
  76. scroll_y_offset_ = event->y_offset();
  77. scroll_x_offset_ordinal_ = event->x_offset_ordinal();
  78. scroll_y_offset_ordinal_ = event->y_offset_ordinal();
  79. }
  80. event->StopPropagation();
  81. }
  82. gfx::Point GetLocationAndReset() {
  83. gfx::Point result = mouse_location_;
  84. mouse_location_.SetPoint(0, 0);
  85. target_root_ = nullptr;
  86. return result;
  87. }
  88. float touch_radius_x() const { return touch_radius_x_; }
  89. float touch_radius_y() const { return touch_radius_y_; }
  90. float scroll_x_offset() const { return scroll_x_offset_; }
  91. float scroll_y_offset() const { return scroll_y_offset_; }
  92. float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; }
  93. float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; }
  94. private:
  95. gfx::Point mouse_location_;
  96. aura::Window* target_root_;
  97. float touch_radius_x_;
  98. float touch_radius_y_;
  99. float scroll_x_offset_;
  100. float scroll_y_offset_;
  101. float scroll_x_offset_ordinal_;
  102. float scroll_y_offset_ordinal_;
  103. };
  104. class RootWindowTransformersTest : public AshTestBase {
  105. public:
  106. RootWindowTransformersTest() = default;
  107. RootWindowTransformersTest(const RootWindowTransformersTest&) = delete;
  108. RootWindowTransformersTest& operator=(const RootWindowTransformersTest&) =
  109. delete;
  110. ~RootWindowTransformersTest() override = default;
  111. float GetStoredZoomScale(int64_t id) {
  112. return display_manager()->GetDisplayInfo(id).zoom_factor();
  113. }
  114. std::unique_ptr<RootWindowTransformer>
  115. CreateCurrentRootWindowTransformerForMirroring() {
  116. DCHECK(display_manager()->IsInMirrorMode());
  117. const display::ManagedDisplayInfo& mirror_display_info =
  118. display_manager()->GetDisplayInfo(
  119. display_manager()->GetMirroringDestinationDisplayIdList()[0]);
  120. const display::ManagedDisplayInfo& source_display_info =
  121. display_manager()->GetDisplayInfo(
  122. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  123. return CreateRootWindowTransformerForMirroredDisplay(source_display_info,
  124. mirror_display_info);
  125. }
  126. };
  127. class UnifiedRootWindowTransformersTest : public RootWindowTransformersTest {
  128. public:
  129. void SetUp() override {
  130. RootWindowTransformersTest::SetUp();
  131. display_manager()->SetUnifiedDesktopEnabled(true);
  132. }
  133. };
  134. } // namespace
  135. TEST_F(RootWindowTransformersTest, RotateAndMagnify) {
  136. FullscreenMagnifierController* magnifier =
  137. Shell::Get()->fullscreen_magnifier_controller();
  138. TestEventHandler event_handler;
  139. Shell::Get()->AddPreTargetHandler(&event_handler);
  140. UpdateDisplay("120x200,300x400*2");
  141. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  142. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  143. int64_t display2_id = display_manager_test.GetSecondaryDisplay().id();
  144. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  145. ui::test::EventGenerator generator1(root_windows[0]);
  146. ui::test::EventGenerator generator2(root_windows[1]);
  147. magnifier->SetEnabled(true);
  148. EXPECT_EQ(2.0f, magnifier->GetScale());
  149. EXPECT_EQ(gfx::Size(120, 200), root_windows[0]->bounds().size());
  150. EXPECT_EQ(gfx::Size(150, 200), root_windows[1]->bounds().size());
  151. EXPECT_EQ(gfx::Rect(120, 0, 150, 200),
  152. display_manager_test.GetSecondaryDisplay().bounds());
  153. generator1.MoveMouseToInHost(40, 80);
  154. EXPECT_EQ(gfx::Point(50, 90), event_handler.GetLocationAndReset());
  155. EXPECT_EQ(gfx::Point(50, 90),
  156. aura::Env::GetInstance()->last_mouse_location());
  157. EXPECT_EQ(display::Display::ROTATE_0,
  158. GetActiveDisplayRotation(display1.id()));
  159. EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
  160. magnifier->SetEnabled(false);
  161. display_manager()->SetDisplayRotation(
  162. display1.id(), display::Display::ROTATE_90,
  163. display::Display::RotationSource::ACTIVE);
  164. // Move the cursor to the center of the first root window.
  165. generator1.MoveMouseToInHost(59, 100);
  166. magnifier->SetEnabled(true);
  167. EXPECT_EQ(2.0f, magnifier->GetScale());
  168. EXPECT_EQ(gfx::Size(200, 120), root_windows[0]->bounds().size());
  169. EXPECT_EQ(gfx::Size(150, 200), root_windows[1]->bounds().size());
  170. EXPECT_EQ(gfx::Rect(200, 0, 150, 200),
  171. display_manager_test.GetSecondaryDisplay().bounds());
  172. generator1.MoveMouseToInHost(39, 120);
  173. EXPECT_EQ(gfx::Point(110, 70), event_handler.GetLocationAndReset());
  174. EXPECT_EQ(gfx::Point(110, 70),
  175. aura::Env::GetInstance()->last_mouse_location());
  176. EXPECT_EQ(display::Display::ROTATE_90,
  177. GetActiveDisplayRotation(display1.id()));
  178. EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
  179. magnifier->SetEnabled(false);
  180. display_manager()->SetLayoutForCurrentDisplays(
  181. display::test::CreateDisplayLayout(
  182. display_manager(), display::DisplayPlacement::BOTTOM, 50));
  183. EXPECT_EQ(gfx::Rect(50, 120, 150, 200),
  184. display_manager_test.GetSecondaryDisplay().bounds());
  185. display_manager()->SetDisplayRotation(
  186. display2_id, display::Display::ROTATE_270,
  187. display::Display::RotationSource::ACTIVE);
  188. // Move the cursor to the center of the second root window.
  189. generator2.MoveMouseToInHost(151, 199);
  190. magnifier->SetEnabled(true);
  191. EXPECT_EQ(gfx::Size(200, 120), root_windows[0]->bounds().size());
  192. EXPECT_EQ(gfx::Size(200, 150), root_windows[1]->bounds().size());
  193. EXPECT_EQ(gfx::Rect(50, 120, 200, 150),
  194. display_manager_test.GetSecondaryDisplay().bounds());
  195. generator2.MoveMouseToInHost(172, 219);
  196. EXPECT_EQ(gfx::Point(95, 80), event_handler.GetLocationAndReset());
  197. EXPECT_EQ(gfx::Point(145, 200),
  198. aura::Env::GetInstance()->last_mouse_location());
  199. EXPECT_EQ(display::Display::ROTATE_90,
  200. GetActiveDisplayRotation(display1.id()));
  201. EXPECT_EQ(display::Display::ROTATE_270,
  202. GetActiveDisplayRotation(display2_id));
  203. magnifier->SetEnabled(false);
  204. display_manager()->SetDisplayRotation(
  205. display1.id(), display::Display::ROTATE_180,
  206. display::Display::RotationSource::ACTIVE);
  207. // Move the cursor to the center of the first root window.
  208. generator1.MoveMouseToInHost(59, 99);
  209. magnifier->SetEnabled(true);
  210. EXPECT_EQ(gfx::Size(120, 200), root_windows[0]->bounds().size());
  211. EXPECT_EQ(gfx::Size(200, 150), root_windows[1]->bounds().size());
  212. // Display must share at least 100, so the x's offset becomes 20.
  213. EXPECT_EQ(gfx::Rect(20, 200, 200, 150),
  214. display_manager_test.GetSecondaryDisplay().bounds());
  215. generator1.MoveMouseToInHost(39, 59);
  216. EXPECT_EQ(gfx::Point(70, 120), event_handler.GetLocationAndReset());
  217. EXPECT_EQ(display::Display::ROTATE_180,
  218. GetActiveDisplayRotation(display1.id()));
  219. EXPECT_EQ(display::Display::ROTATE_270,
  220. GetActiveDisplayRotation(display2_id));
  221. magnifier->SetEnabled(false);
  222. Shell::Get()->RemovePreTargetHandler(&event_handler);
  223. }
  224. TEST_F(RootWindowTransformersTest, ScaleAndMagnify) {
  225. TestEventHandler event_handler;
  226. Shell::Get()->AddPreTargetHandler(&event_handler);
  227. UpdateDisplay("600x400*1.6,500x300");
  228. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  229. display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
  230. display1.id());
  231. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  232. display::Display display2 = display_manager_test.GetSecondaryDisplay();
  233. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  234. FullscreenMagnifierController* magnifier =
  235. Shell::Get()->fullscreen_magnifier_controller();
  236. magnifier->SetEnabled(true);
  237. EXPECT_EQ(2.0f, magnifier->GetScale());
  238. EXPECT_EQ(1.6f, display1.device_scale_factor());
  239. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), display1.bounds());
  240. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), root_windows[0]->bounds());
  241. EXPECT_EQ(gfx::Rect(375, 0, 500, 300), display2.bounds());
  242. EXPECT_EQ(1.0f, GetStoredZoomScale(display1.id()));
  243. EXPECT_EQ(1.0f, GetStoredZoomScale(display2.id()));
  244. ui::test::EventGenerator generator(root_windows[0]);
  245. generator.MoveMouseToInHost(500, 200);
  246. EXPECT_EQ(gfx::Point(249, 124), event_handler.GetLocationAndReset());
  247. magnifier->SetEnabled(false);
  248. display_manager()->UpdateZoomFactor(display1.id(), 1.f / 1.2f);
  249. display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  250. display2 = display_manager_test.GetSecondaryDisplay();
  251. magnifier->SetEnabled(true);
  252. EXPECT_EQ(2.0f, magnifier->GetScale());
  253. EXPECT_EQ(gfx::Rect(0, 0, 450, 300), display1.bounds());
  254. EXPECT_EQ(gfx::Rect(0, 0, 450, 300), root_windows[0]->bounds());
  255. EXPECT_EQ(gfx::Rect(450, 0, 500, 300), display2.bounds());
  256. EXPECT_FLOAT_EQ(1.f / 1.2f, GetStoredZoomScale(display1.id()));
  257. EXPECT_EQ(1.0f, GetStoredZoomScale(display2.id()));
  258. magnifier->SetEnabled(false);
  259. Shell::Get()->RemovePreTargetHandler(&event_handler);
  260. }
  261. TEST_F(RootWindowTransformersTest, TouchScaleAndMagnify) {
  262. TestEventHandler event_handler;
  263. Shell::Get()->AddPreTargetHandler(&event_handler);
  264. UpdateDisplay("300x200*2");
  265. display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
  266. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  267. aura::Window* root_window = root_windows[0];
  268. ui::test::EventGenerator generator(root_window);
  269. FullscreenMagnifierController* magnifier =
  270. Shell::Get()->fullscreen_magnifier_controller();
  271. magnifier->SetEnabled(true);
  272. EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
  273. magnifier->SetScale(2.5f, false);
  274. EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale());
  275. generator.PressMoveAndReleaseTouchTo(50, 50);
  276. // Default test touches have radius_x/y = 1.0, with device scale
  277. // factor = 2, the scaled radius_x/y should be 0.5.
  278. EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_x());
  279. EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_y());
  280. generator.ScrollSequence(gfx::Point(0, 0), base::Milliseconds(100), 10.0, 1.0,
  281. 5, 1);
  282. // ordinal_offset is invariant to the device scale factor.
  283. EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(),
  284. event_handler.scroll_x_offset_ordinal());
  285. EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(),
  286. event_handler.scroll_y_offset_ordinal());
  287. magnifier->SetEnabled(false);
  288. Shell::Get()->RemovePreTargetHandler(&event_handler);
  289. }
  290. TEST_F(RootWindowTransformersTest, ConvertHostToRootCoords) {
  291. TestEventHandler event_handler;
  292. Shell::Get()->AddPreTargetHandler(&event_handler);
  293. FullscreenMagnifierController* magnifier =
  294. Shell::Get()->fullscreen_magnifier_controller();
  295. // Test 1
  296. UpdateDisplay("600x400*2/r@0.8");
  297. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  298. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  299. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), display1.bounds());
  300. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), root_windows[0]->bounds());
  301. EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
  302. ui::test::EventGenerator generator(root_windows[0]);
  303. generator.MoveMouseToInHost(300, 200);
  304. magnifier->SetEnabled(true);
  305. EXPECT_EQ(gfx::Point(125, 187), event_handler.GetLocationAndReset());
  306. EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
  307. generator.MoveMouseToInHost(300, 200);
  308. EXPECT_EQ(gfx::Point(124, 186), event_handler.GetLocationAndReset());
  309. generator.MoveMouseToInHost(200, 300);
  310. EXPECT_EQ(gfx::Point(155, 218), event_handler.GetLocationAndReset());
  311. generator.MoveMouseToInHost(100, 400);
  312. EXPECT_EQ(gfx::Point(204, 249), event_handler.GetLocationAndReset());
  313. generator.MoveMouseToInHost(0, 0);
  314. EXPECT_EQ(gfx::Point(125, 298), event_handler.GetLocationAndReset());
  315. magnifier->SetEnabled(false);
  316. EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
  317. // Test 2
  318. UpdateDisplay("600x400*2/u@0.8");
  319. display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  320. root_windows = Shell::GetAllRootWindows();
  321. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), display1.bounds());
  322. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), root_windows[0]->bounds());
  323. EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
  324. generator.MoveMouseToInHost(300, 200);
  325. magnifier->SetEnabled(true);
  326. EXPECT_EQ(gfx::Point(187, 125), event_handler.GetLocationAndReset());
  327. EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
  328. generator.MoveMouseToInHost(300, 200);
  329. EXPECT_EQ(gfx::Point(186, 124), event_handler.GetLocationAndReset());
  330. generator.MoveMouseToInHost(200, 300);
  331. EXPECT_EQ(gfx::Point(218, 93), event_handler.GetLocationAndReset());
  332. generator.MoveMouseToInHost(100, 400);
  333. EXPECT_EQ(gfx::Point(249, 43), event_handler.GetLocationAndReset());
  334. generator.MoveMouseToInHost(0, 0);
  335. EXPECT_EQ(gfx::Point(298, 125), event_handler.GetLocationAndReset());
  336. magnifier->SetEnabled(false);
  337. EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
  338. // Test 3
  339. UpdateDisplay("600x400*2/l@0.8");
  340. display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  341. root_windows = Shell::GetAllRootWindows();
  342. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), display1.bounds());
  343. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), root_windows[0]->bounds());
  344. EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
  345. generator.MoveMouseToInHost(300, 200);
  346. magnifier->SetEnabled(true);
  347. EXPECT_EQ(gfx::Point(125, 187), event_handler.GetLocationAndReset());
  348. EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
  349. generator.MoveMouseToInHost(300, 200);
  350. EXPECT_EQ(gfx::Point(124, 186), event_handler.GetLocationAndReset());
  351. generator.MoveMouseToInHost(200, 300);
  352. EXPECT_EQ(gfx::Point(93, 155), event_handler.GetLocationAndReset());
  353. generator.MoveMouseToInHost(100, 400);
  354. EXPECT_EQ(gfx::Point(43, 124), event_handler.GetLocationAndReset());
  355. generator.MoveMouseToInHost(0, 0);
  356. EXPECT_EQ(gfx::Point(125, 74), event_handler.GetLocationAndReset());
  357. magnifier->SetEnabled(false);
  358. EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
  359. Shell::Get()->RemovePreTargetHandler(&event_handler);
  360. }
  361. TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) {
  362. MirrorWindowTestApi test_api;
  363. // Letter boxed
  364. UpdateDisplay("400x200,500x400");
  365. display_manager()->SetMirrorMode(display::MirrorMode::kNormal, absl::nullopt);
  366. std::unique_ptr<RootWindowTransformer> transformer(
  367. CreateCurrentRootWindowTransformerForMirroring());
  368. // Y margin must be margin is (400 - 500/400 * 200) / 2 = 75
  369. EXPECT_EQ(gfx::Insets::TLBR(0, 75, 0, 75), transformer->GetHostInsets());
  370. // Pillar boxed
  371. UpdateDisplay("200x400,500x400");
  372. // X margin must be margin is (500 - 200) / 2 = 150
  373. transformer = CreateCurrentRootWindowTransformerForMirroring();
  374. EXPECT_EQ(gfx::Insets::TLBR(150, 0, 150, 0), transformer->GetHostInsets());
  375. }
  376. TEST_F(RootWindowTransformersTest, MirrorWithRotation) {
  377. MirrorWindowTestApi test_api;
  378. UpdateDisplay("400x200,500x400");
  379. display_manager()->SetMirrorMode(display::MirrorMode::kNormal, absl::nullopt);
  380. for (auto rotation :
  381. {display::Display::ROTATE_0, display::Display::ROTATE_90,
  382. display::Display::ROTATE_180, display::Display::ROTATE_270}) {
  383. SCOPED_TRACE(::testing::Message() << "Rotation: " << rotation);
  384. display_manager()->SetDisplayRotation(
  385. display::Screen::GetScreen()->GetPrimaryDisplay().id(), rotation,
  386. display::Display::RotationSource::ACTIVE);
  387. std::unique_ptr<RootWindowTransformer> transformer(
  388. CreateCurrentRootWindowTransformerForMirroring());
  389. const bool need_transpose = rotation == display::Display::ROTATE_90 ||
  390. rotation == display::Display::ROTATE_270;
  391. // Y margin is (400 - 500/400 * 200) / 2 = 75 for no rotation. Transposed
  392. // on 90/270 degree.
  393. gfx::Insets expected_insets =
  394. need_transpose ? gfx::Insets::VH(75, 0) : gfx::Insets::VH(0, 75);
  395. EXPECT_EQ(expected_insets, transformer->GetHostInsets());
  396. // Expected rect in mirror of the source root, with y margin applied for no
  397. // rotation. Transposed on 90/270 degree.
  398. gfx::RectF expected_rect(0, 75, 500, 250);
  399. if (need_transpose)
  400. expected_rect.Transpose();
  401. gfx::RectF rect(transformer->GetRootWindowBounds(gfx::Size()));
  402. transformer->GetTransform().TransformRect(&rect);
  403. EXPECT_EQ(expected_rect, rect);
  404. }
  405. }
  406. TEST_F(RootWindowTransformersTest, ShouldSetWindowSize) {
  407. UpdateDisplay("800x600");
  408. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  409. aura::Window* root_window = root_windows[0];
  410. // Rotate screen 90 degrees to "right".
  411. // Will triger window_tree_host->SetRootWindowTransformer().
  412. // The window size will be updated because there is no ongoing transform
  413. // animation.
  414. UpdateDisplay("800x600/r");
  415. EXPECT_EQ(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
  416. }
  417. TEST_F(RootWindowTransformersTest,
  418. ShouldNotSetWindowSizeWithEnqueuedTransformAnimation) {
  419. UpdateDisplay("800x600");
  420. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  421. aura::Window* root_window = root_windows[0];
  422. ui::ScopedAnimationDurationScaleMode test_duration(
  423. ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
  424. ui::Layer* layer = root_window->layer();
  425. {
  426. ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
  427. settings.SetTransitionDuration(base::Milliseconds(100));
  428. gfx::Transform transform;
  429. transform.Translate(100, 200);
  430. layer->SetTransform(transform);
  431. }
  432. layer->GetAnimator()->set_preemption_strategy(
  433. ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
  434. // Rotate screen 90 degrees to "right".
  435. // Will triger window_tree_host->SetRootWindowTransformer().
  436. // The window size will not be updated because there is ongoing transform
  437. // animation.
  438. UpdateDisplay("800x600/r");
  439. EXPECT_NE(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
  440. }
  441. TEST_F(RootWindowTransformersTest,
  442. ShouldSetWindowSizeWithStoppedTransformAnimation) {
  443. UpdateDisplay("800x600");
  444. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  445. aura::Window* root_window = root_windows[0];
  446. ui::ScopedAnimationDurationScaleMode test_duration(
  447. ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
  448. ui::Layer* layer = root_window->layer();
  449. {
  450. ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
  451. settings.SetTransitionDuration(base::Milliseconds(100));
  452. gfx::Transform transform;
  453. transform.Translate(100, 200);
  454. layer->SetTransform(transform);
  455. }
  456. layer->GetAnimator()->set_preemption_strategy(
  457. ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
  458. // Rotate screen 90 degrees to "right".
  459. // Will triger window_tree_host->SetRootWindowTransformer().
  460. // The window size will be updated because there is no ongoing transform
  461. // animation.
  462. UpdateDisplay("800x600/r");
  463. EXPECT_EQ(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
  464. }
  465. TEST_F(RootWindowTransformersTest, ShouldSetWindowSizeDuringOpacityAnimation) {
  466. UpdateDisplay("800x600");
  467. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  468. aura::Window* root_window = root_windows[0];
  469. ui::ScopedAnimationDurationScaleMode test_duration(
  470. ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
  471. {
  472. ui::Layer* layer = root_window->layer();
  473. ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
  474. settings.SetTransitionDuration(base::Milliseconds(100));
  475. layer->SetOpacity(0.1f);
  476. }
  477. // Rotate screen 90 degrees to "right".
  478. // Will triger window_tree_host->SetRootWindowTransformer().
  479. // The window size will be updated because there is no ongoing transform
  480. // animation, even there is an opacity animation.
  481. UpdateDisplay("800x600/r");
  482. EXPECT_EQ(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
  483. }
  484. TEST_F(UnifiedRootWindowTransformersTest, HostBoundsAndTransform) {
  485. UpdateDisplay("800x600,800x600");
  486. // Has only one logical root window.
  487. EXPECT_EQ(1u, Shell::GetAllRootWindows().size());
  488. MirrorWindowTestApi test_api;
  489. std::vector<aura::WindowTreeHost*> hosts = test_api.GetHosts();
  490. // Have 2 WindowTreeHosts, one per display.
  491. ASSERT_EQ(2u, hosts.size());
  492. EXPECT_EQ(gfx::Rect(0, 0, 800, 600), hosts[0]->window()->GetBoundsInScreen());
  493. gfx::Point viewport_0_origin(0, 0);
  494. hosts[0]->window()->transform().TransformPointReverse(&viewport_0_origin);
  495. EXPECT_EQ(gfx::Point(0, 0), viewport_0_origin);
  496. EXPECT_EQ(gfx::Rect(800, 0, 800, 600),
  497. hosts[1]->window()->GetBoundsInScreen());
  498. gfx::Point viewport_1_origin(0, 0);
  499. hosts[1]->window()->transform().TransformPointReverse(&viewport_1_origin);
  500. EXPECT_EQ(gfx::Point(800, 0), viewport_1_origin);
  501. }
  502. TEST_F(UnifiedRootWindowTransformersTest,
  503. PrimaryDisplayRotationAndInputEvents) {
  504. TestEventHandler event_handler;
  505. Shell::Get()->AddPreTargetHandler(&event_handler);
  506. // Use different sized displays with primary display rotated to the right.
  507. UpdateDisplay("1920x1080*2/r,800x600");
  508. EXPECT_TRUE(display_manager()->IsInUnifiedMode());
  509. // Has only one logical root window.
  510. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  511. EXPECT_EQ(1u, root_windows.size());
  512. MirrorWindowTestApi test_api;
  513. std::vector<aura::WindowTreeHost*> hosts = test_api.GetHosts();
  514. // Have 2 WindowTreeHosts, one per display.
  515. ASSERT_EQ(2u, hosts.size());
  516. EXPECT_EQ(display::Display::ROTATE_90,
  517. GetActiveDisplayRotation(hosts[0]->GetDisplayId()));
  518. EXPECT_EQ(display::Display::ROTATE_0,
  519. GetActiveDisplayRotation(hosts[1]->GetDisplayId()));
  520. EXPECT_EQ(gfx::Rect(0, 0, 1080, 1920),
  521. hosts[0]->window()->GetBoundsInScreen());
  522. gfx::Point viewport_0_origin(0, 0);
  523. EXPECT_TRUE(hosts[0]->window()->transform().TransformPointReverse(
  524. &viewport_0_origin));
  525. EXPECT_EQ(gfx::Point(0, 0), viewport_0_origin);
  526. gfx::Point viewport_0_bottom_right(1000, 1900);
  527. EXPECT_TRUE(hosts[0]->window()->transform().TransformPointReverse(
  528. &viewport_0_bottom_right));
  529. EXPECT_EQ(gfx::Point(1000, 1900), viewport_0_bottom_right);
  530. EXPECT_EQ(gfx::Rect(1080, 0, 800, 600),
  531. hosts[1]->window()->GetBoundsInScreen());
  532. gfx::Point viewport_1_origin(0, 0);
  533. EXPECT_TRUE(hosts[1]->window()->transform().TransformPointReverse(
  534. &viewport_1_origin));
  535. EXPECT_EQ(gfx::Point(1080, 0), viewport_1_origin);
  536. gfx::Point viewport_1_bottom_right(800, 600);
  537. EXPECT_TRUE(hosts[1]->window()->transform().TransformPointReverse(
  538. &viewport_1_bottom_right));
  539. // Since the first display is rotated, the unified height is 1920.
  540. // The 2nd display's height of 600 is scaled to this: 1920/600=3.2.
  541. // So the bottom right corner of the 2nd display has
  542. // x=1080+(800*3.2)=3640 and y=0+(600*3.2)=1920.
  543. EXPECT_EQ(gfx::Point(3640, 1920), viewport_1_bottom_right);
  544. // Mouse input on the 1st display.
  545. ui::test::EventGenerator generator0(hosts[0]->window());
  546. generator0.MoveMouseToInHost(0, 0);
  547. // x=0/2=0 y=(1920-0)/2=960
  548. // But y=959 because it's at the bottom edge.
  549. EXPECT_EQ(gfx::Point(0, 959), event_handler.GetLocationAndReset());
  550. generator0.MoveMouseToInHost(300, 200);
  551. // x=200/2=100 y=(1920-300)/2=810
  552. EXPECT_EQ(gfx::Point(100, 810), event_handler.GetLocationAndReset());
  553. generator0.MoveMouseToInHost(1900, 1050);
  554. // x=1050/2=525 y=(1920-1900)/2=10
  555. EXPECT_EQ(gfx::Point(525, 10), event_handler.GetLocationAndReset());
  556. // Mouse input on the 2nd display.
  557. ui::test::EventGenerator generator1(hosts[1]->window());
  558. generator1.MoveMouseToInHost(0, 0);
  559. // x=(1080+(0*3.2))/2=540 y=0*3.2/2=0
  560. EXPECT_EQ(gfx::Point(540, 0), event_handler.GetLocationAndReset());
  561. generator1.MoveMouseToInHost(100, 200);
  562. // x=(1080+(100*3.2))/2=700 y=200*3.2/2=320
  563. EXPECT_EQ(gfx::Point(700, 320), event_handler.GetLocationAndReset());
  564. generator1.MoveMouseToInHost(600, 500);
  565. // x=(1080+(600*3.2))/2=1500 y=500*3.2/2=800
  566. EXPECT_EQ(gfx::Point(1500, 800), event_handler.GetLocationAndReset());
  567. Shell::Get()->RemovePreTargetHandler(&event_handler);
  568. }
  569. TEST_F(UnifiedRootWindowTransformersTest,
  570. SecondaryDisplayRotationAndInputEvents) {
  571. TestEventHandler event_handler;
  572. Shell::Get()->AddPreTargetHandler(&event_handler);
  573. // Use different sized displays with secondary display rotated to the right.
  574. UpdateDisplay("1920x1080*2,800x600/r");
  575. EXPECT_TRUE(display_manager()->IsInUnifiedMode());
  576. // Has only one logical root window.
  577. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  578. EXPECT_EQ(1u, root_windows.size());
  579. MirrorWindowTestApi test_api;
  580. std::vector<aura::WindowTreeHost*> hosts = test_api.GetHosts();
  581. // Have 2 WindowTreeHosts, one per display.
  582. ASSERT_EQ(2u, hosts.size());
  583. EXPECT_EQ(display::Display::ROTATE_0,
  584. GetActiveDisplayRotation(hosts[0]->GetDisplayId()));
  585. EXPECT_EQ(display::Display::ROTATE_90,
  586. GetActiveDisplayRotation(hosts[1]->GetDisplayId()));
  587. EXPECT_EQ(gfx::Rect(0, 0, 1920, 1080),
  588. hosts[0]->window()->GetBoundsInScreen());
  589. gfx::Point viewport_0_origin(0, 0);
  590. EXPECT_TRUE(hosts[0]->window()->transform().TransformPointReverse(
  591. &viewport_0_origin));
  592. EXPECT_EQ(gfx::Point(0, 0), viewport_0_origin);
  593. gfx::Point viewport_0_bottom_right(1900, 1000);
  594. EXPECT_TRUE(hosts[0]->window()->transform().TransformPointReverse(
  595. &viewport_0_bottom_right));
  596. EXPECT_EQ(gfx::Point(1900, 1000), viewport_0_bottom_right);
  597. EXPECT_EQ(gfx::Rect(1920, 0, 600, 800),
  598. hosts[1]->window()->GetBoundsInScreen());
  599. gfx::Point viewport_1_origin(0, 0);
  600. EXPECT_TRUE(hosts[1]->window()->transform().TransformPointReverse(
  601. &viewport_1_origin));
  602. EXPECT_EQ(gfx::Point(1920, 0), viewport_1_origin);
  603. gfx::Point viewport_1_bottom_right(600, 800);
  604. EXPECT_TRUE(hosts[1]->window()->transform().TransformPointReverse(
  605. &viewport_1_bottom_right));
  606. // Since the 2nd display is rotated, its height is 800. This is scaled to the
  607. // height of the 1st display, which is 1080. So the 2nd display's scaling is
  608. // 1080/800=1.35. So the bottom right corner of the 2nd display has
  609. // x=1920+(600*1.35)=2730 and y=0+(800*1.35)=1080.
  610. EXPECT_EQ(gfx::Point(2730, 1080), viewport_1_bottom_right);
  611. // Mouse input on the 1st display.
  612. ui::test::EventGenerator generator0(hosts[0]->window());
  613. generator0.MoveMouseToInHost(0, 0);
  614. EXPECT_EQ(gfx::Point(0, 0), event_handler.GetLocationAndReset());
  615. generator0.MoveMouseToInHost(300, 200);
  616. EXPECT_EQ(gfx::Point(150, 100), event_handler.GetLocationAndReset());
  617. generator0.MoveMouseToInHost(1900, 1000);
  618. EXPECT_EQ(gfx::Point(950, 500), event_handler.GetLocationAndReset());
  619. // Mouse input on the 2nd display.
  620. ui::test::EventGenerator generator1(hosts[1]->window());
  621. generator1.MoveMouseToInHost(0, 0);
  622. // x=(1920+(0*1.35))/2=960 y=(800-0)*1.35/2=540
  623. // But y=539 because it's at the bottom edge.
  624. EXPECT_EQ(gfx::Point(960, 539), event_handler.GetLocationAndReset());
  625. generator1.MoveMouseToInHost(100, 200);
  626. // x=(1920+(200*1.35))/2=1095 y=(800-100)*1.35/2=472.5
  627. EXPECT_EQ(gfx::Point(1095, 472), event_handler.GetLocationAndReset());
  628. generator1.MoveMouseToInHost(700, 500);
  629. // x=(1920+(500*1.35))/2=1297.5 y=(800-700)*1.35/2=67.5
  630. EXPECT_EQ(gfx::Point(1297, 67), event_handler.GetLocationAndReset());
  631. // Now rotate the 2nd display to the left.
  632. UpdateDisplay("1920x1080*2,800x600/l");
  633. EXPECT_TRUE(display_manager()->IsInUnifiedMode());
  634. hosts = test_api.GetHosts();
  635. // Have 2 WindowTreeHosts, one per display.
  636. ASSERT_EQ(2u, hosts.size());
  637. EXPECT_EQ(display::Display::ROTATE_270,
  638. GetActiveDisplayRotation(hosts[1]->GetDisplayId()));
  639. EXPECT_EQ(gfx::Rect(1920, 0, 600, 800),
  640. hosts[1]->window()->GetBoundsInScreen());
  641. // Mouse input on the 2nd display.
  642. ui::test::EventGenerator generator2(hosts[1]->window());
  643. generator2.MoveMouseToInHost(0, 0);
  644. // x=(1920+((600-0)*1.35))/2=1365 y=0*1.35/2=0
  645. // But x=1364 because it's at the right most edge.
  646. EXPECT_EQ(gfx::Point(1364, 0), event_handler.GetLocationAndReset());
  647. generator2.MoveMouseToInHost(100, 200);
  648. // x=(1920+((600-200)*1.35))/2=1230 y=100*1.35/2=67.5
  649. EXPECT_EQ(gfx::Point(1230, 67), event_handler.GetLocationAndReset());
  650. generator2.MoveMouseToInHost(110, 210);
  651. // x=(1920+((600-210)*1.35))/2=1223.25 y=110*1.35/2=74.25
  652. EXPECT_EQ(gfx::Point(1223, 74), event_handler.GetLocationAndReset());
  653. Shell::Get()->RemovePreTargetHandler(&event_handler);
  654. }
  655. } // namespace ash