window_tree_host_manager_unittest.cc 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937
  1. // Copyright (c) 2012 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/window_tree_host_manager.h"
  5. #include <memory>
  6. #include "ash/display/display_util.h"
  7. #include "ash/public/cpp/shelf_config.h"
  8. #include "ash/screen_util.h"
  9. #include "ash/shelf/shelf.h"
  10. #include "ash/shelf/shelf_widget.h"
  11. #include "ash/shell.h"
  12. #include "ash/test/ash_test_base.h"
  13. #include "ash/test/ash_test_helper.h"
  14. #include "ash/test/test_widget_builder.h"
  15. #include "ash/test_shell_delegate.h"
  16. #include "ash/wm/cursor_manager_test_api.h"
  17. #include "ash/wm/window_state.h"
  18. #include "ash/wm/wm_event.h"
  19. #include "base/command_line.h"
  20. #include "base/run_loop.h"
  21. #include "base/test/scoped_feature_list.h"
  22. #include "ui/aura/client/focus_change_observer.h"
  23. #include "ui/aura/client/focus_client.h"
  24. #include "ui/aura/env.h"
  25. #include "ui/aura/window_observer.h"
  26. #include "ui/aura/window_tracker.h"
  27. #include "ui/aura/window_tree_host.h"
  28. #include "ui/base/cursor/cursor.h"
  29. #include "ui/compositor/layer.h"
  30. #include "ui/display/display.h"
  31. #include "ui/display/display_features.h"
  32. #include "ui/display/display_layout.h"
  33. #include "ui/display/display_layout_builder.h"
  34. #include "ui/display/display_observer.h"
  35. #include "ui/display/display_switches.h"
  36. #include "ui/display/manager/display_layout_store.h"
  37. #include "ui/display/manager/display_manager.h"
  38. #include "ui/display/manager/managed_display_info.h"
  39. #include "ui/display/screen.h"
  40. #include "ui/display/test/display_manager_test_api.h"
  41. #include "ui/events/event_handler.h"
  42. #include "ui/events/keycodes/keyboard_codes.h"
  43. #include "ui/events/test/event_generator.h"
  44. #include "ui/events/types/event_type.h"
  45. #include "ui/gfx/geometry/rounded_corners_f.h"
  46. #include "ui/views/event_monitor.h"
  47. #include "ui/views/mouse_watcher.h"
  48. #include "ui/views/mouse_watcher_view_host.h"
  49. #include "ui/views/view.h"
  50. #include "ui/views/widget/widget.h"
  51. #include "ui/wm/core/cursor_manager.h"
  52. #include "ui/wm/public/activation_change_observer.h"
  53. #include "ui/wm/public/activation_client.h"
  54. namespace ash {
  55. namespace {
  56. const char kWallpaperView[] = "WallpaperViewWidget";
  57. template <typename T>
  58. class Resetter {
  59. public:
  60. explicit Resetter(T* value) : value_(*value) { *value = 0; }
  61. Resetter(const Resetter&) = delete;
  62. Resetter& operator=(const Resetter&) = delete;
  63. ~Resetter() = default;
  64. T value() { return value_; }
  65. private:
  66. T value_;
  67. };
  68. class TestObserver : public WindowTreeHostManager::Observer,
  69. public display::DisplayObserver,
  70. public aura::client::FocusChangeObserver,
  71. public ::wm::ActivationChangeObserver {
  72. public:
  73. TestObserver() {
  74. Shell::Get()->window_tree_host_manager()->AddObserver(this);
  75. aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())
  76. ->AddObserver(this);
  77. ::wm::GetActivationClient(Shell::GetPrimaryRootWindow())->AddObserver(this);
  78. }
  79. TestObserver(const TestObserver&) = delete;
  80. TestObserver& operator=(const TestObserver&) = delete;
  81. ~TestObserver() override {
  82. Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
  83. aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())
  84. ->RemoveObserver(this);
  85. ::wm::GetActivationClient(Shell::GetPrimaryRootWindow())
  86. ->RemoveObserver(this);
  87. }
  88. // Overridden from WindowTreeHostManager::Observer
  89. void OnDisplayConfigurationChanging() override { ++changing_count_; }
  90. void OnDisplayConfigurationChanged() override { ++changed_count_; }
  91. // Overrideen from display::DisplayObserver
  92. void OnDisplayMetricsChanged(const display::Display& display,
  93. uint32_t metrics) override {
  94. changed_display_id_ = display.id();
  95. if (metrics & DISPLAY_METRIC_BOUNDS)
  96. ++bounds_changed_count_;
  97. if (metrics & DISPLAY_METRIC_ROTATION)
  98. ++rotation_changed_count_;
  99. if (metrics & DISPLAY_METRIC_WORK_AREA)
  100. ++workarea_changed_count_;
  101. if (metrics & DISPLAY_METRIC_PRIMARY)
  102. ++primary_changed_count_;
  103. }
  104. // Overridden from aura::client::FocusChangeObserver
  105. void OnWindowFocused(aura::Window* gained_focus,
  106. aura::Window* lost_focus) override {
  107. focus_changed_count_++;
  108. }
  109. // Overridden from wm::ActivationChangeObserver
  110. void OnWindowActivated(
  111. ::wm::ActivationChangeObserver::ActivationReason reason,
  112. aura::Window* gained_active,
  113. aura::Window* lost_active) override {
  114. activation_changed_count_++;
  115. }
  116. void OnAttemptToReactivateWindow(aura::Window* request_active,
  117. aura::Window* actual_active) override {}
  118. int CountAndReset() {
  119. EXPECT_EQ(changing_count_, changed_count_);
  120. changed_count_ = 0;
  121. return Resetter<int>(&changing_count_).value();
  122. }
  123. int64_t GetBoundsChangedCountAndReset() {
  124. return Resetter<int>(&bounds_changed_count_).value();
  125. }
  126. int64_t GetRotationChangedCountAndReset() {
  127. return Resetter<int>(&rotation_changed_count_).value();
  128. }
  129. int64_t GetWorkareaChangedCountAndReset() {
  130. return Resetter<int>(&workarea_changed_count_).value();
  131. }
  132. int64_t GetPrimaryChangedCountAndReset() {
  133. return Resetter<int>(&primary_changed_count_).value();
  134. }
  135. int64_t GetChangedDisplayIdAndReset() {
  136. return Resetter<int64_t>(&changed_display_id_).value();
  137. }
  138. int GetFocusChangedCountAndReset() {
  139. return Resetter<int>(&focus_changed_count_).value();
  140. }
  141. int GetActivationChangedCountAndReset() {
  142. return Resetter<int>(&activation_changed_count_).value();
  143. }
  144. private:
  145. int changing_count_ = 0;
  146. int changed_count_ = 0;
  147. int bounds_changed_count_ = 0;
  148. int rotation_changed_count_ = 0;
  149. int workarea_changed_count_ = 0;
  150. int primary_changed_count_ = 0;
  151. int64_t changed_display_id_ = 0;
  152. int focus_changed_count_ = 0;
  153. int activation_changed_count_ = 0;
  154. display::ScopedDisplayObserver display_observer_{this};
  155. };
  156. class TestHelper {
  157. public:
  158. explicit TestHelper(AshTestBase* delegate);
  159. TestHelper(const TestHelper&) = delete;
  160. TestHelper& operator=(const TestHelper&) = delete;
  161. ~TestHelper();
  162. void SetSecondaryDisplayLayoutAndOffset(
  163. display::DisplayPlacement::Position position,
  164. int offset);
  165. void SetSecondaryDisplayLayout(display::DisplayPlacement::Position position);
  166. void SetDefaultDisplayLayout(display::DisplayPlacement::Position position);
  167. float GetStoredZoomScale(int64_t id);
  168. private:
  169. AshTestBase* delegate_; // Not owned
  170. };
  171. TestHelper::TestHelper(AshTestBase* delegate) : delegate_(delegate) {}
  172. TestHelper::~TestHelper() = default;
  173. void TestHelper::SetSecondaryDisplayLayoutAndOffset(
  174. display::DisplayPlacement::Position position,
  175. int offset) {
  176. std::unique_ptr<display::DisplayLayout> layout(
  177. display::test::CreateDisplayLayout(delegate_->display_manager(), position,
  178. offset));
  179. ASSERT_GT(display::Screen::GetScreen()->GetNumDisplays(), 1);
  180. delegate_->display_manager()->SetLayoutForCurrentDisplays(std::move(layout));
  181. }
  182. void TestHelper::SetSecondaryDisplayLayout(
  183. display::DisplayPlacement::Position position) {
  184. SetSecondaryDisplayLayoutAndOffset(position, 0);
  185. }
  186. void TestHelper::SetDefaultDisplayLayout(
  187. display::DisplayPlacement::Position position) {
  188. display::DisplayPlacement default_placement(position, 0);
  189. delegate_->display_manager()->layout_store()->SetDefaultDisplayPlacement(
  190. default_placement);
  191. }
  192. float TestHelper::GetStoredZoomScale(int64_t id) {
  193. return delegate_->display_manager()->GetDisplayInfo(id).zoom_factor();
  194. }
  195. class WindowTreeHostManagerShutdownTest : public AshTestBase,
  196. public TestHelper {
  197. public:
  198. WindowTreeHostManagerShutdownTest() : TestHelper(this) {}
  199. WindowTreeHostManagerShutdownTest(const WindowTreeHostManagerShutdownTest&) =
  200. delete;
  201. WindowTreeHostManagerShutdownTest& operator=(
  202. const WindowTreeHostManagerShutdownTest&) = delete;
  203. ~WindowTreeHostManagerShutdownTest() override = default;
  204. void TearDown() override {
  205. AshTestBase::TearDown();
  206. // Make sure that primary display is accessible after shutdown.
  207. display::Display primary =
  208. display::Screen::GetScreen()->GetPrimaryDisplay();
  209. EXPECT_EQ(gfx::Rect(0, 0, 444, 333), primary.bounds());
  210. EXPECT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  211. }
  212. };
  213. class WindowTreeHostManagerStartupTest : public AshTestBase, public TestHelper {
  214. public:
  215. WindowTreeHostManagerStartupTest() : TestHelper(this) {}
  216. WindowTreeHostManagerStartupTest(const WindowTreeHostManagerStartupTest&) =
  217. delete;
  218. WindowTreeHostManagerStartupTest& operator=(
  219. const WindowTreeHostManagerStartupTest&) = delete;
  220. ~WindowTreeHostManagerStartupTest() override = default;
  221. };
  222. class TestEventHandler : public ui::EventHandler {
  223. public:
  224. TestEventHandler()
  225. : target_root_(nullptr),
  226. touch_radius_x_(0.0),
  227. touch_radius_y_(0.0),
  228. scroll_x_offset_(0.0),
  229. scroll_y_offset_(0.0),
  230. scroll_x_offset_ordinal_(0.0),
  231. scroll_y_offset_ordinal_(0.0) {}
  232. TestEventHandler(const TestEventHandler&) = delete;
  233. TestEventHandler& operator=(const TestEventHandler&) = delete;
  234. ~TestEventHandler() override = default;
  235. void OnMouseEvent(ui::MouseEvent* event) override {
  236. if (event->flags() & ui::EF_IS_SYNTHESIZED &&
  237. event->type() != ui::ET_MOUSE_EXITED &&
  238. event->type() != ui::ET_MOUSE_ENTERED) {
  239. return;
  240. }
  241. aura::Window* target = static_cast<aura::Window*>(event->target());
  242. mouse_location_ = event->root_location();
  243. target_root_ = target->GetRootWindow();
  244. event->StopPropagation();
  245. }
  246. void OnTouchEvent(ui::TouchEvent* event) override {
  247. aura::Window* target = static_cast<aura::Window*>(event->target());
  248. // Only record when the target is the wallpaper, which covers the entire
  249. // root window.
  250. if (target->GetName() != kWallpaperView)
  251. return;
  252. touch_radius_x_ = event->pointer_details().radius_x;
  253. touch_radius_y_ = event->pointer_details().radius_y;
  254. event->StopPropagation();
  255. }
  256. void OnScrollEvent(ui::ScrollEvent* event) override {
  257. aura::Window* target = static_cast<aura::Window*>(event->target());
  258. // Only record when the target is the wallpaper, which covers the entire
  259. // root window.
  260. if (target->GetName() != kWallpaperView)
  261. return;
  262. if (event->type() == ui::ET_SCROLL) {
  263. scroll_x_offset_ = event->x_offset();
  264. scroll_y_offset_ = event->y_offset();
  265. scroll_x_offset_ordinal_ = event->x_offset_ordinal();
  266. scroll_y_offset_ordinal_ = event->y_offset_ordinal();
  267. }
  268. event->StopPropagation();
  269. }
  270. gfx::Point GetLocationAndReset() {
  271. gfx::Point result = mouse_location_;
  272. mouse_location_.SetPoint(0, 0);
  273. target_root_ = nullptr;
  274. return result;
  275. }
  276. float touch_radius_x() { return touch_radius_x_; }
  277. float touch_radius_y() { return touch_radius_y_; }
  278. float scroll_x_offset() { return scroll_x_offset_; }
  279. float scroll_y_offset() { return scroll_y_offset_; }
  280. float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; }
  281. float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; }
  282. private:
  283. gfx::Point mouse_location_;
  284. aura::Window* target_root_;
  285. float touch_radius_x_;
  286. float touch_radius_y_;
  287. float scroll_x_offset_;
  288. float scroll_y_offset_;
  289. float scroll_x_offset_ordinal_;
  290. float scroll_y_offset_ordinal_;
  291. };
  292. class TestMouseWatcherListener : public views::MouseWatcherListener {
  293. public:
  294. TestMouseWatcherListener() = default;
  295. TestMouseWatcherListener(const TestMouseWatcherListener&) = delete;
  296. TestMouseWatcherListener& operator=(const TestMouseWatcherListener&) = delete;
  297. private:
  298. // views::MouseWatcherListener:
  299. void MouseMovedOutOfHost() override {}
  300. };
  301. } // namespace
  302. class WindowTreeHostManagerTest : public AshTestBase, public TestHelper {
  303. public:
  304. WindowTreeHostManagerTest() : TestHelper(this) {}
  305. WindowTreeHostManagerTest(const WindowTreeHostManagerTest&) = delete;
  306. WindowTreeHostManagerTest& operator=(const WindowTreeHostManagerTest&) =
  307. delete;
  308. ~WindowTreeHostManagerTest() override = default;
  309. };
  310. TEST_F(WindowTreeHostManagerShutdownTest, Shutdown) {
  311. UpdateDisplay("444x333, 300x200");
  312. }
  313. TEST_F(WindowTreeHostManagerStartupTest, Startup) {
  314. // Ensure that WindowTreeHostManager was initialized and created at least one
  315. // root window.
  316. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  317. EXPECT_FALSE(root_windows.empty());
  318. }
  319. TEST_F(WindowTreeHostManagerTest, SecondaryDisplayLayout) {
  320. // Creates windows to catch activation change event.
  321. std::unique_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
  322. w1->Focus();
  323. TestObserver observer;
  324. UpdateDisplay("600x500,500x400");
  325. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  326. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  327. EXPECT_EQ(2, observer.GetWorkareaChangedCountAndReset());
  328. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  329. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  330. gfx::Insets insets(5);
  331. int64_t secondary_display_id =
  332. display::test::DisplayManagerTestApi(display_manager())
  333. .GetSecondaryDisplay()
  334. .id();
  335. display_manager()->UpdateWorkAreaOfDisplay(secondary_display_id, insets);
  336. // Default layout is RIGHT.
  337. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  338. EXPECT_EQ(gfx::Rect(600, 0, 500, 400), GetSecondaryDisplay().bounds());
  339. EXPECT_EQ(gfx::Rect(605, 5, 490, 390), GetSecondaryDisplay().work_area());
  340. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  341. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  342. // Layout the secondary display to the bottom of the primary.
  343. SetSecondaryDisplayLayout(display::DisplayPlacement::BOTTOM);
  344. EXPECT_EQ(1, observer.CountAndReset());
  345. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  346. // TODO (oshima): work area changes twice because ShelfLayoutManager updates
  347. // to its own insets.
  348. EXPECT_EQ(2, observer.GetWorkareaChangedCountAndReset());
  349. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  350. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  351. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  352. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  353. EXPECT_EQ(gfx::Rect(0, 500, 500, 400), GetSecondaryDisplay().bounds());
  354. EXPECT_EQ(gfx::Rect(5, 505, 490, 390), GetSecondaryDisplay().work_area());
  355. // Layout the secondary display to the left of the primary.
  356. SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT);
  357. EXPECT_EQ(1, observer.CountAndReset());
  358. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  359. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  360. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  361. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  362. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  363. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  364. EXPECT_EQ(gfx::Rect(-500, 0, 500, 400), GetSecondaryDisplay().bounds());
  365. EXPECT_EQ(gfx::Rect(-495, 5, 490, 390), GetSecondaryDisplay().work_area());
  366. // Layout the secondary display to the top of the primary.
  367. SetSecondaryDisplayLayout(display::DisplayPlacement::TOP);
  368. EXPECT_EQ(1, observer.CountAndReset());
  369. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  370. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  371. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  372. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  373. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  374. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  375. EXPECT_EQ(gfx::Rect(0, -400, 500, 400), GetSecondaryDisplay().bounds());
  376. EXPECT_EQ(gfx::Rect(5, -395, 490, 390), GetSecondaryDisplay().work_area());
  377. // Layout to the right with an offset.
  378. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::RIGHT, 300);
  379. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  380. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  381. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  382. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  383. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  384. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  385. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  386. EXPECT_EQ(gfx::Rect(600, 300, 500, 400), GetSecondaryDisplay().bounds());
  387. // Keep the minimum 100.
  388. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::RIGHT, 490);
  389. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  390. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  391. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  392. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  393. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  394. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  395. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  396. EXPECT_EQ(gfx::Rect(600, 400, 500, 400), GetSecondaryDisplay().bounds());
  397. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::RIGHT, -400);
  398. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  399. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  400. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  401. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  402. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  403. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  404. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  405. EXPECT_EQ(gfx::Rect(600, -300, 500, 400), GetSecondaryDisplay().bounds());
  406. // Layout to the bottom with an offset.
  407. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::BOTTOM, -200);
  408. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  409. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  410. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  411. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  412. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  413. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  414. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  415. EXPECT_EQ(gfx::Rect(-200, 500, 500, 400), GetSecondaryDisplay().bounds());
  416. // Keep the minimum 100.
  417. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::BOTTOM, 590);
  418. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  419. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  420. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  421. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  422. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  423. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  424. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  425. EXPECT_EQ(gfx::Rect(500, 500, 500, 400), GetSecondaryDisplay().bounds());
  426. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::BOTTOM, -500);
  427. EXPECT_EQ(secondary_display_id, observer.GetChangedDisplayIdAndReset());
  428. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  429. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  430. EXPECT_EQ(1, observer.CountAndReset()); // resize and add
  431. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  432. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  433. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  434. EXPECT_EQ(gfx::Rect(-400, 500, 500, 400), GetSecondaryDisplay().bounds());
  435. // Setting the same layout shouldn't invoke observers.
  436. SetSecondaryDisplayLayoutAndOffset(display::DisplayPlacement::BOTTOM, -500);
  437. EXPECT_EQ(0, observer.GetChangedDisplayIdAndReset());
  438. EXPECT_EQ(0, observer.GetBoundsChangedCountAndReset());
  439. EXPECT_EQ(0, observer.GetWorkareaChangedCountAndReset());
  440. EXPECT_EQ(0, observer.CountAndReset()); // resize and add
  441. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  442. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  443. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), GetPrimaryDisplay().bounds());
  444. EXPECT_EQ(gfx::Rect(-400, 500, 500, 400), GetSecondaryDisplay().bounds());
  445. UpdateDisplay("600x500");
  446. EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
  447. EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
  448. }
  449. namespace {
  450. display::ManagedDisplayInfo
  451. CreateDisplayInfo(int64_t id, int y, display::Display::Rotation rotation) {
  452. display::ManagedDisplayInfo info(id, "", false);
  453. info.SetBounds(gfx::Rect(0, y, 600, 500));
  454. info.SetRotation(rotation, display::Display::RotationSource::ACTIVE);
  455. return info;
  456. }
  457. display::ManagedDisplayInfo CreateMirroredDisplayInfo(
  458. int64_t id,
  459. float device_scale_factor) {
  460. display::ManagedDisplayInfo info =
  461. CreateDisplayInfo(id, 0, display::Display::ROTATE_0);
  462. info.set_device_scale_factor(device_scale_factor);
  463. return info;
  464. }
  465. } // namespace
  466. TEST_F(WindowTreeHostManagerTest, MirrorToDockedWithFullscreen) {
  467. // Creates windows to catch activation change event.
  468. std::unique_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
  469. w1->Focus();
  470. // Docked mode.
  471. const display::ManagedDisplayInfo internal_display_info =
  472. CreateMirroredDisplayInfo(1, 2.0f);
  473. const display::ManagedDisplayInfo external_display_info =
  474. CreateMirroredDisplayInfo(2, 1.0f);
  475. std::vector<display::ManagedDisplayInfo> display_info_list;
  476. // Mirror.
  477. display_info_list.push_back(internal_display_info);
  478. display_info_list.push_back(external_display_info);
  479. display_manager()->OnNativeDisplaysChanged(display_info_list);
  480. const int64_t internal_display_id =
  481. display::test::DisplayManagerTestApi(display_manager())
  482. .SetFirstDisplayAsInternalDisplay();
  483. EXPECT_EQ(1, internal_display_id);
  484. EXPECT_EQ(2U, display_manager()->num_connected_displays());
  485. EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  486. WindowState* window_state = WindowState::Get(w1.get());
  487. const WMEvent toggle_fullscreen_event(WM_EVENT_TOGGLE_FULLSCREEN);
  488. window_state->OnWMEvent(&toggle_fullscreen_event);
  489. EXPECT_TRUE(window_state->IsFullscreen());
  490. EXPECT_EQ(gfx::Rect(0, 0, 300, 250), w1->bounds());
  491. // Dock mode.
  492. TestObserver observer;
  493. display_info_list.clear();
  494. display_info_list.push_back(external_display_info);
  495. display_manager()->OnNativeDisplaysChanged(display_info_list);
  496. EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  497. EXPECT_EQ(1U, display_manager()->num_connected_displays());
  498. // Observers are called due to primary change.
  499. EXPECT_EQ(2, observer.GetChangedDisplayIdAndReset());
  500. EXPECT_EQ(1, observer.GetBoundsChangedCountAndReset());
  501. EXPECT_EQ(1, observer.GetWorkareaChangedCountAndReset());
  502. EXPECT_EQ(1, observer.GetPrimaryChangedCountAndReset());
  503. EXPECT_EQ(1, observer.CountAndReset());
  504. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  505. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  506. EXPECT_TRUE(window_state->IsFullscreen());
  507. EXPECT_EQ(gfx::Rect(0, 0, 600, 500), w1->bounds());
  508. }
  509. TEST_F(WindowTreeHostManagerTest, BoundsUpdated) {
  510. // Creates windows to catch activation change event.
  511. std::unique_ptr<aura::Window> w1(CreateTestWindowInShellWithId(1));
  512. w1->Focus();
  513. TestObserver observer;
  514. SetDefaultDisplayLayout(display::DisplayPlacement::BOTTOM);
  515. UpdateDisplay("300x200,400x300"); // layout, resize and add.
  516. EXPECT_EQ(1, observer.CountAndReset());
  517. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  518. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  519. gfx::Insets insets(5);
  520. display_manager()->UpdateWorkAreaOfDisplay(GetSecondaryDisplay().id(),
  521. insets);
  522. EXPECT_EQ(gfx::Rect(0, 0, 300, 200), GetPrimaryDisplay().bounds());
  523. EXPECT_EQ(gfx::Rect(0, 200, 400, 300), GetSecondaryDisplay().bounds());
  524. EXPECT_EQ(gfx::Rect(5, 205, 390, 290), GetSecondaryDisplay().work_area());
  525. UpdateDisplay("500x400,300x200");
  526. EXPECT_EQ(1, observer.CountAndReset()); // two resizes
  527. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  528. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  529. EXPECT_EQ(gfx::Rect(0, 0, 500, 400), GetPrimaryDisplay().bounds());
  530. EXPECT_EQ(gfx::Rect(0, 400, 300, 200), GetSecondaryDisplay().bounds());
  531. UpdateDisplay("500x400,400x300");
  532. EXPECT_EQ(1, observer.CountAndReset());
  533. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  534. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  535. EXPECT_EQ(gfx::Rect(0, 0, 500, 400), GetPrimaryDisplay().bounds());
  536. EXPECT_EQ(gfx::Rect(0, 400, 400, 300), GetSecondaryDisplay().bounds());
  537. UpdateDisplay("500x400");
  538. EXPECT_EQ(1, observer.CountAndReset());
  539. EXPECT_LE(1, observer.GetFocusChangedCountAndReset());
  540. EXPECT_LE(1, observer.GetActivationChangedCountAndReset());
  541. EXPECT_EQ(gfx::Rect(0, 0, 500, 400), GetPrimaryDisplay().bounds());
  542. EXPECT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  543. UpdateDisplay("400x500*2,400x300");
  544. EXPECT_EQ(1, observer.CountAndReset());
  545. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  546. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  547. ASSERT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  548. EXPECT_EQ(gfx::Rect(0, 0, 200, 250), GetPrimaryDisplay().bounds());
  549. EXPECT_EQ(gfx::Rect(0, 250, 400, 300), GetSecondaryDisplay().bounds());
  550. // No change
  551. UpdateDisplay("400x500*2,400x300");
  552. // We still call into Pre/PostDisplayConfigurationChange().
  553. EXPECT_EQ(1, observer.CountAndReset());
  554. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  555. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  556. // Rotation
  557. observer.GetRotationChangedCountAndReset(); // we only want to reset.
  558. int64_t primary_id = GetPrimaryDisplay().id();
  559. display_manager()->SetDisplayRotation(
  560. primary_id, display::Display::ROTATE_90,
  561. display::Display::RotationSource::ACTIVE);
  562. EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
  563. EXPECT_EQ(1, observer.CountAndReset());
  564. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  565. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  566. display_manager()->SetDisplayRotation(
  567. primary_id, display::Display::ROTATE_90,
  568. display::Display::RotationSource::ACTIVE);
  569. EXPECT_EQ(0, observer.GetRotationChangedCountAndReset());
  570. EXPECT_EQ(0, observer.CountAndReset());
  571. EXPECT_EQ(0, observer.GetFocusChangedCountAndReset());
  572. EXPECT_EQ(0, observer.GetActivationChangedCountAndReset());
  573. }
  574. TEST_F(WindowTreeHostManagerTest, FindNearestDisplay) {
  575. WindowTreeHostManager* window_tree_host_manager =
  576. Shell::Get()->window_tree_host_manager();
  577. UpdateDisplay("200x201,300x301");
  578. display_manager()->SetLayoutForCurrentDisplays(
  579. display::test::CreateDisplayLayout(display_manager(),
  580. display::DisplayPlacement::RIGHT, 50));
  581. display::Display primary_display =
  582. display::Screen::GetScreen()->GetPrimaryDisplay();
  583. display::Display secondary_display =
  584. display::test::DisplayManagerTestApi(display_manager())
  585. .GetSecondaryDisplay();
  586. EXPECT_NE(primary_display.id(), secondary_display.id());
  587. aura::Window* primary_root =
  588. window_tree_host_manager->GetRootWindowForDisplayId(primary_display.id());
  589. aura::Window* secondary_root =
  590. window_tree_host_manager->GetRootWindowForDisplayId(
  591. secondary_display.id());
  592. EXPECT_NE(primary_root, secondary_root);
  593. // Test that points outside of any display return the nearest display.
  594. EXPECT_EQ(primary_display.id(),
  595. display::Screen::GetScreen()
  596. ->GetDisplayNearestPoint(gfx::Point(-100, 0))
  597. .id());
  598. EXPECT_EQ(primary_display.id(),
  599. display::Screen::GetScreen()
  600. ->GetDisplayNearestPoint(gfx::Point(0, -100))
  601. .id());
  602. EXPECT_EQ(primary_display.id(),
  603. display::Screen::GetScreen()
  604. ->GetDisplayNearestPoint(gfx::Point(100, 100))
  605. .id());
  606. EXPECT_EQ(primary_display.id(),
  607. display::Screen::GetScreen()
  608. ->GetDisplayNearestPoint(gfx::Point(224, 25))
  609. .id());
  610. EXPECT_EQ(secondary_display.id(),
  611. display::Screen::GetScreen()
  612. ->GetDisplayNearestPoint(gfx::Point(226, 25))
  613. .id());
  614. EXPECT_EQ(secondary_display.id(),
  615. display::Screen::GetScreen()
  616. ->GetDisplayNearestPoint(gfx::Point(600, 100))
  617. .id());
  618. EXPECT_EQ(primary_display.id(),
  619. display::Screen::GetScreen()
  620. ->GetDisplayNearestPoint(gfx::Point(176, 225))
  621. .id());
  622. EXPECT_EQ(secondary_display.id(),
  623. display::Screen::GetScreen()
  624. ->GetDisplayNearestPoint(gfx::Point(178, 225))
  625. .id());
  626. EXPECT_EQ(secondary_display.id(),
  627. display::Screen::GetScreen()
  628. ->GetDisplayNearestPoint(gfx::Point(300, 400))
  629. .id());
  630. }
  631. TEST_F(WindowTreeHostManagerTest,
  632. SettingAndUpdatingRoundedCornerPropertyOnDisplay) {
  633. base::test::ScopedFeatureList scoped_feature_list;
  634. scoped_feature_list.InitAndEnableFeature(display::features::kRoundedDisplay);
  635. WindowTreeHostManager* window_tree_host_manager =
  636. Shell::Get()->window_tree_host_manager();
  637. // Adding rounded corners on the primary display.
  638. UpdateDisplay("300x200~15");
  639. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  640. aura::Window* primary_root = Shell::GetPrimaryRootWindow();
  641. EXPECT_EQ(gfx::RoundedCornersF(15.0),
  642. primary_root->layer()->rounded_corner_radii());
  643. // Adding a secondary display should not propagate the rounded corner
  644. // property.
  645. UpdateDisplay("300x200~15,300x200");
  646. display::Display secondary_display =
  647. display_manager_test.GetSecondaryDisplay();
  648. aura::Window* secondary_root =
  649. window_tree_host_manager->GetRootWindowForDisplayId(
  650. secondary_display.id());
  651. EXPECT_EQ(gfx::RoundedCornersF(15.0),
  652. primary_root->layer()->rounded_corner_radii());
  653. EXPECT_EQ(primary_root->layer()->is_fast_rounded_corner(), true);
  654. EXPECT_EQ(gfx::RoundedCornersF(0.0),
  655. secondary_root->layer()->rounded_corner_radii());
  656. // Removing the secondary display should not effect the rounded corner
  657. // property.
  658. UpdateDisplay("300x200~15");
  659. EXPECT_EQ(gfx::RoundedCornersF(15.0),
  660. primary_root->layer()->rounded_corner_radii());
  661. EXPECT_EQ(primary_root->layer()->is_fast_rounded_corner(), true);
  662. // Changing the the metrics should not effect rounded corner property.
  663. UpdateDisplay("10+20-300x200/ol~15");
  664. EXPECT_EQ(gfx::RoundedCornersF(15.0),
  665. primary_root->layer()->rounded_corner_radii());
  666. EXPECT_EQ(primary_root->layer()->is_fast_rounded_corner(), true);
  667. // Updating rounded corners property on the display.
  668. UpdateDisplay("300x200~15|15|12|12");
  669. EXPECT_EQ(gfx::RoundedCornersF(15.0, 15.0, 12.0, 12.0),
  670. primary_root->layer()->rounded_corner_radii());
  671. EXPECT_EQ(primary_root->layer()->is_fast_rounded_corner(), true);
  672. }
  673. TEST_F(WindowTreeHostManagerTest,
  674. SwappingPrimaryDisplayShouldNotSwapRoundedCornersOnDisplays) {
  675. base::test::ScopedFeatureList scoped_feature_list;
  676. scoped_feature_list.InitAndEnableFeature(display::features::kRoundedDisplay);
  677. WindowTreeHostManager* window_tree_host_manager =
  678. Shell::Get()->window_tree_host_manager();
  679. // primary display has rounded corners.
  680. UpdateDisplay("300x200~15,400x300");
  681. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  682. display::Display secondary_display =
  683. display_manager_test.GetSecondaryDisplay();
  684. aura::Window* primary_root = Shell::GetPrimaryRootWindow();
  685. aura::Window* secondary_root =
  686. window_tree_host_manager->GetRootWindowForDisplayId(
  687. secondary_display.id());
  688. EXPECT_EQ(gfx::RoundedCornersF(15.0),
  689. primary_root->layer()->rounded_corner_radii());
  690. EXPECT_EQ(primary_root->layer()->is_fast_rounded_corner(), true);
  691. EXPECT_EQ(gfx::RoundedCornersF(0.0),
  692. secondary_root->layer()->rounded_corner_radii());
  693. // Switch primary and secondary by display ID.
  694. window_tree_host_manager->SetPrimaryDisplayId(secondary_display.id());
  695. // Getting the new primary and secondary root windows after the swap.
  696. secondary_display = display_manager_test.GetSecondaryDisplay();
  697. primary_root = Shell::GetPrimaryRootWindow();
  698. secondary_root = window_tree_host_manager->GetRootWindowForDisplayId(
  699. secondary_display.id());
  700. // After swapping primary display, the root windows are swapped. Secondary
  701. // root now belongs to the display with rounded corners.
  702. EXPECT_EQ(gfx::RoundedCornersF(15.0),
  703. secondary_root->layer()->rounded_corner_radii());
  704. EXPECT_EQ(secondary_root->layer()->is_fast_rounded_corner(), true);
  705. EXPECT_EQ(gfx::RoundedCornersF(0.0),
  706. primary_root->layer()->rounded_corner_radii());
  707. }
  708. TEST_F(WindowTreeHostManagerTest, SwapPrimaryById) {
  709. WindowTreeHostManager* window_tree_host_manager =
  710. Shell::Get()->window_tree_host_manager();
  711. UpdateDisplay("300x200,400x300/h");
  712. const int shelf_inset_first = 200 - ShelfConfig::Get()->shelf_size();
  713. const int shelf_inset_second = 300 - ShelfConfig::Get()->shelf_size();
  714. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  715. display::Display primary_display =
  716. display::Screen::GetScreen()->GetPrimaryDisplay();
  717. display::Display secondary_display =
  718. display_manager_test.GetSecondaryDisplay();
  719. display_manager()->SetLayoutForCurrentDisplays(
  720. display::test::CreateDisplayLayout(display_manager(),
  721. display::DisplayPlacement::RIGHT, 50));
  722. EXPECT_NE(primary_display.id(), secondary_display.id());
  723. aura::Window* primary_root =
  724. window_tree_host_manager->GetRootWindowForDisplayId(primary_display.id());
  725. aura::Window* secondary_root =
  726. window_tree_host_manager->GetRootWindowForDisplayId(
  727. secondary_display.id());
  728. aura::Window* shelf_window =
  729. GetPrimaryShelf()->shelf_widget()->GetNativeView();
  730. EXPECT_TRUE(primary_root->Contains(shelf_window));
  731. EXPECT_FALSE(secondary_root->Contains(shelf_window));
  732. EXPECT_NE(primary_root, secondary_root);
  733. EXPECT_EQ(primary_display.id(),
  734. display::Screen::GetScreen()
  735. ->GetDisplayNearestPoint(gfx::Point(-100, -100))
  736. .id());
  737. EXPECT_EQ(
  738. primary_display.id(),
  739. display::Screen::GetScreen()->GetDisplayNearestWindow(nullptr).id());
  740. EXPECT_EQ(gfx::Rect(0, 0, 300, 200), primary_display.bounds());
  741. EXPECT_EQ(gfx::Rect(0, 0, 300, shelf_inset_first),
  742. primary_display.work_area());
  743. EXPECT_EQ(gfx::Rect(300, 0, 400, 300), secondary_display.bounds());
  744. EXPECT_EQ(gfx::Rect(300, 0, 400, shelf_inset_second),
  745. secondary_display.work_area());
  746. EXPECT_EQ("id=2200000257, parent=2200000000, right, 50",
  747. display_manager()
  748. ->GetCurrentDisplayLayout()
  749. .placement_list[0]
  750. .ToString());
  751. // Switch primary and secondary by display ID.
  752. TestObserver observer;
  753. window_tree_host_manager->SetPrimaryDisplayId(secondary_display.id());
  754. EXPECT_EQ(secondary_display.id(),
  755. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  756. EXPECT_EQ(primary_display.id(),
  757. display_manager_test.GetSecondaryDisplay().id());
  758. EXPECT_LT(0, observer.CountAndReset());
  759. EXPECT_EQ(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  760. secondary_display.id()));
  761. EXPECT_EQ(secondary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  762. primary_display.id()));
  763. EXPECT_TRUE(primary_root->Contains(shelf_window));
  764. EXPECT_FALSE(secondary_root->Contains(shelf_window));
  765. const display::DisplayLayout& inverted_layout =
  766. display_manager()->GetCurrentDisplayLayout();
  767. EXPECT_EQ("id=2200000000, parent=2200000257, left, -50",
  768. inverted_layout.placement_list[0].ToString());
  769. // Test if the bounds are correctly swapped.
  770. display::Display swapped_primary =
  771. display::Screen::GetScreen()->GetPrimaryDisplay();
  772. display::Display swapped_secondary =
  773. display_manager_test.GetSecondaryDisplay();
  774. EXPECT_EQ(gfx::Rect(0, 0, 400, 300), swapped_primary.bounds());
  775. EXPECT_EQ(gfx::Rect(0, 0, 400, shelf_inset_second),
  776. swapped_primary.work_area());
  777. EXPECT_EQ(gfx::Rect(-300, -50, 300, 200), swapped_secondary.bounds());
  778. EXPECT_EQ(gfx::Rect(-300, -50, 300, shelf_inset_first),
  779. swapped_secondary.work_area());
  780. // Test that the color spaces are correctly swapped.
  781. auto* swapped_primary_compositor =
  782. window_tree_host_manager->GetRootWindowForDisplayId(swapped_primary.id())
  783. ->GetHost()
  784. ->compositor();
  785. auto* swapped_secondary_compositor =
  786. window_tree_host_manager
  787. ->GetRootWindowForDisplayId(swapped_secondary.id())
  788. ->GetHost()
  789. ->compositor();
  790. EXPECT_EQ(swapped_primary.color_spaces(),
  791. swapped_primary_compositor->display_color_spaces());
  792. EXPECT_EQ(swapped_secondary.color_spaces(),
  793. swapped_secondary_compositor->display_color_spaces());
  794. // Calling the same ID don't do anything.
  795. window_tree_host_manager->SetPrimaryDisplayId(secondary_display.id());
  796. EXPECT_EQ(0, observer.CountAndReset());
  797. aura::WindowTracker tracker;
  798. tracker.Add(primary_root);
  799. tracker.Add(secondary_root);
  800. // Deleting 2nd display should move the primary to original primary display.
  801. UpdateDisplay("300x200");
  802. base::RunLoop().RunUntilIdle(); // RootWindow is deleted in a posted task.
  803. EXPECT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  804. EXPECT_EQ(primary_display.id(),
  805. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  806. EXPECT_EQ(primary_display.id(),
  807. display::Screen::GetScreen()
  808. ->GetDisplayNearestPoint(gfx::Point(-100, -100))
  809. .id());
  810. EXPECT_EQ(
  811. primary_display.id(),
  812. display::Screen::GetScreen()->GetDisplayNearestWindow(nullptr).id());
  813. EXPECT_TRUE(tracker.Contains(primary_root));
  814. EXPECT_FALSE(tracker.Contains(secondary_root));
  815. EXPECT_TRUE(primary_root->Contains(shelf_window));
  816. // Adding 2nd display with the same ID. The 2nd display should become primary
  817. // since secondary id is still stored as desirable_primary_id.
  818. std::vector<display::ManagedDisplayInfo> display_info_list;
  819. display_info_list.push_back(
  820. display_manager()->GetDisplayInfo(primary_display.id()));
  821. display_info_list.push_back(
  822. display_manager()->GetDisplayInfo(secondary_display.id()));
  823. display_manager()->OnNativeDisplaysChanged(display_info_list);
  824. EXPECT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  825. EXPECT_EQ(secondary_display.id(),
  826. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  827. EXPECT_EQ(primary_display.id(),
  828. display_manager_test.GetSecondaryDisplay().id());
  829. EXPECT_EQ(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  830. secondary_display.id()));
  831. EXPECT_NE(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  832. primary_display.id()));
  833. EXPECT_TRUE(primary_root->Contains(shelf_window));
  834. // Deleting 2nd display and adding 2nd display with a different ID. The 2nd
  835. // display shouldn't become primary.
  836. UpdateDisplay("300x200");
  837. display::ManagedDisplayInfo third_display_info(secondary_display.id() + 1,
  838. std::string(), false);
  839. third_display_info.SetBounds(secondary_display.bounds());
  840. ASSERT_NE(primary_display.id(), third_display_info.id());
  841. const display::ManagedDisplayInfo& primary_display_info =
  842. display_manager()->GetDisplayInfo(primary_display.id());
  843. std::vector<display::ManagedDisplayInfo> display_info_list2;
  844. display_info_list2.push_back(primary_display_info);
  845. display_info_list2.push_back(third_display_info);
  846. display_manager()->OnNativeDisplaysChanged(display_info_list2);
  847. EXPECT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  848. EXPECT_EQ(primary_display.id(),
  849. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  850. EXPECT_EQ(third_display_info.id(),
  851. display_manager_test.GetSecondaryDisplay().id());
  852. EXPECT_EQ(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  853. primary_display.id()));
  854. EXPECT_NE(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  855. third_display_info.id()));
  856. EXPECT_TRUE(primary_root->Contains(shelf_window));
  857. }
  858. TEST_F(WindowTreeHostManagerTest, SetPrimaryWithThreeDisplays) {
  859. UpdateDisplay("500x400,400x300,300x200");
  860. int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  861. display::DisplayIdList non_primary_ids =
  862. display_manager()->GetConnectedDisplayIdList();
  863. auto itr =
  864. std::remove(non_primary_ids.begin(), non_primary_ids.end(), primary_id);
  865. ASSERT_TRUE(itr != non_primary_ids.end());
  866. non_primary_ids.erase(itr, non_primary_ids.end());
  867. ASSERT_EQ(2u, non_primary_ids.size());
  868. // Build the following layout:
  869. //
  870. // +----------------+ +--------------------+
  871. // | primary_id (P) | <---- | non_primary_ids[0] |
  872. // +----------------+ +--------------------+
  873. // ^
  874. // |
  875. // +--------------------+
  876. // | non_primary_ids[1] |
  877. // +--------------------+
  878. display::DisplayLayoutBuilder builder(primary_id);
  879. builder.AddDisplayPlacement(non_primary_ids[0], primary_id,
  880. display::DisplayPlacement::RIGHT, 0);
  881. builder.AddDisplayPlacement(non_primary_ids[1], primary_id,
  882. display::DisplayPlacement::BOTTOM, 0);
  883. display_manager()->SetLayoutForCurrentDisplays(builder.Build());
  884. EXPECT_EQ(primary_id, display::Screen::GetScreen()->GetPrimaryDisplay().id());
  885. WindowTreeHostManager* window_tree_host_manager =
  886. Shell::Get()->window_tree_host_manager();
  887. aura::Window* primary_root =
  888. window_tree_host_manager->GetRootWindowForDisplayId(primary_id);
  889. aura::Window* non_primary_root_0 =
  890. window_tree_host_manager->GetRootWindowForDisplayId(non_primary_ids[0]);
  891. aura::Window* non_primary_root_1 =
  892. window_tree_host_manager->GetRootWindowForDisplayId(non_primary_ids[1]);
  893. // Make non_primary_ids[0] primary.
  894. window_tree_host_manager->SetPrimaryDisplayId(non_primary_ids[0]);
  895. EXPECT_EQ(non_primary_ids[0],
  896. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  897. // Expect the root windows to be swapped.
  898. EXPECT_EQ(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  899. non_primary_ids[0]));
  900. EXPECT_EQ(non_primary_root_0,
  901. window_tree_host_manager->GetRootWindowForDisplayId(primary_id));
  902. EXPECT_EQ(
  903. non_primary_root_1,
  904. window_tree_host_manager->GetRootWindowForDisplayId(non_primary_ids[1]));
  905. // Expect that the layout will be changed to:
  906. //
  907. // +----------------+ +-----------------------+
  908. // | primary_id | ----> | non_primary_ids[0] (P)|
  909. // +----------------+ +-----------------------+
  910. // ^
  911. // |
  912. // +--------------------+
  913. // | non_primary_ids[1] |
  914. // +--------------------+
  915. {
  916. const display::DisplayLayout& current_layout =
  917. display_manager()->GetCurrentDisplayLayout();
  918. EXPECT_EQ(non_primary_ids[0], current_layout.primary_id);
  919. ASSERT_EQ(2u, current_layout.placement_list.size());
  920. EXPECT_EQ(primary_id, current_layout.placement_list[0].display_id);
  921. EXPECT_EQ(non_primary_ids[0],
  922. current_layout.placement_list[0].parent_display_id);
  923. EXPECT_EQ(display::DisplayPlacement::LEFT,
  924. current_layout.placement_list[0].position);
  925. EXPECT_EQ(non_primary_ids[1], current_layout.placement_list[1].display_id);
  926. EXPECT_EQ(primary_id, current_layout.placement_list[1].parent_display_id);
  927. EXPECT_EQ(display::DisplayPlacement::BOTTOM,
  928. current_layout.placement_list[1].position);
  929. }
  930. // Make non_primary_ids[1] primary.
  931. window_tree_host_manager->SetPrimaryDisplayId(non_primary_ids[1]);
  932. EXPECT_EQ(non_primary_ids[1],
  933. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  934. // Expect the root windows to be swapped.
  935. EXPECT_EQ(primary_root, window_tree_host_manager->GetRootWindowForDisplayId(
  936. non_primary_ids[1]));
  937. EXPECT_EQ(
  938. non_primary_root_1,
  939. window_tree_host_manager->GetRootWindowForDisplayId(non_primary_ids[0]));
  940. EXPECT_EQ(non_primary_root_0,
  941. window_tree_host_manager->GetRootWindowForDisplayId(primary_id));
  942. // Expect that the layout will be changed to:
  943. //
  944. // +----------------+ +--------------------+
  945. // | primary_id | <---- | non_primary_ids[0] |
  946. // +----------------+ +--------------------+
  947. // |
  948. // V
  949. // +------------------------+
  950. // | non_primary_ids[1] (P) |
  951. // +------------------------+
  952. {
  953. const display::DisplayLayout& current_layout =
  954. display_manager()->GetCurrentDisplayLayout();
  955. EXPECT_EQ(non_primary_ids[1], current_layout.primary_id);
  956. ASSERT_EQ(2u, current_layout.placement_list.size());
  957. EXPECT_EQ(primary_id, current_layout.placement_list[0].display_id);
  958. EXPECT_EQ(non_primary_ids[1],
  959. current_layout.placement_list[0].parent_display_id);
  960. EXPECT_EQ(display::DisplayPlacement::TOP,
  961. current_layout.placement_list[0].position);
  962. EXPECT_EQ(non_primary_ids[0], current_layout.placement_list[1].display_id);
  963. EXPECT_EQ(primary_id, current_layout.placement_list[1].parent_display_id);
  964. EXPECT_EQ(display::DisplayPlacement::RIGHT,
  965. current_layout.placement_list[1].position);
  966. }
  967. }
  968. TEST_F(WindowTreeHostManagerTest, SetPrimaryWithFourDisplays) {
  969. UpdateDisplay("600x500,500x400,400x300,300x200");
  970. int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  971. display::DisplayIdList non_primary_ids =
  972. display_manager()->GetConnectedDisplayIdList();
  973. auto itr =
  974. std::remove(non_primary_ids.begin(), non_primary_ids.end(), primary_id);
  975. ASSERT_TRUE(itr != non_primary_ids.end());
  976. non_primary_ids.erase(itr, non_primary_ids.end());
  977. ASSERT_EQ(3u, non_primary_ids.size());
  978. // Build the following layout:
  979. //
  980. // +--------------------+ +--------------------+ +--------------------+
  981. // | | | primary_id (P) | | |
  982. // | | +--------------------+ | |
  983. // | | ^ | |
  984. // | non_primary_ids[1] | | | non_primary_ids[2] |
  985. // | | +--------------------+ | |
  986. // | |-->| non_primary_ids[0] |<--| |
  987. // +--------------------+ +--------------------+ +--------------------+
  988. display::DisplayLayoutBuilder builder(primary_id);
  989. builder.AddDisplayPlacement(non_primary_ids[0], primary_id,
  990. display::DisplayPlacement::BOTTOM, 0);
  991. builder.AddDisplayPlacement(non_primary_ids[1], non_primary_ids[0],
  992. display::DisplayPlacement::LEFT, 0);
  993. builder.AddDisplayPlacement(non_primary_ids[2], non_primary_ids[0],
  994. display::DisplayPlacement::RIGHT, 0);
  995. display_manager()->SetLayoutForCurrentDisplays(builder.Build());
  996. EXPECT_EQ(primary_id, display::Screen::GetScreen()->GetPrimaryDisplay().id());
  997. WindowTreeHostManager* window_tree_host_manager =
  998. Shell::Get()->window_tree_host_manager();
  999. // Make non_primary_ids[2] primary.
  1000. window_tree_host_manager->SetPrimaryDisplayId(non_primary_ids[2]);
  1001. EXPECT_EQ(non_primary_ids[2],
  1002. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  1003. // Expect that the layout will be changed to:
  1004. //
  1005. // +--------------------+ +--------------------+ +--------------------+
  1006. // | | | primary_id | | |
  1007. // | | +--------------------+ | |
  1008. // | | | | |
  1009. // | non_primary_ids[1] | V | non_primary_ids[2] |
  1010. // | | +--------------------+ | (P) |
  1011. // | |-->| non_primary_ids[0] |-->| |
  1012. // +--------------------+ +--------------------+ +--------------------+
  1013. {
  1014. const display::DisplayLayout& current_layout =
  1015. display_manager()->GetCurrentDisplayLayout();
  1016. EXPECT_EQ(non_primary_ids[2], current_layout.primary_id);
  1017. ASSERT_EQ(3u, current_layout.placement_list.size());
  1018. EXPECT_EQ(primary_id, current_layout.placement_list[0].display_id);
  1019. EXPECT_EQ(non_primary_ids[0],
  1020. current_layout.placement_list[0].parent_display_id);
  1021. EXPECT_EQ(display::DisplayPlacement::TOP,
  1022. current_layout.placement_list[0].position);
  1023. EXPECT_EQ(non_primary_ids[0], current_layout.placement_list[1].display_id);
  1024. EXPECT_EQ(non_primary_ids[2],
  1025. current_layout.placement_list[1].parent_display_id);
  1026. EXPECT_EQ(display::DisplayPlacement::LEFT,
  1027. current_layout.placement_list[1].position);
  1028. EXPECT_EQ(non_primary_ids[1], current_layout.placement_list[2].display_id);
  1029. EXPECT_EQ(non_primary_ids[0],
  1030. current_layout.placement_list[2].parent_display_id);
  1031. EXPECT_EQ(display::DisplayPlacement::LEFT,
  1032. current_layout.placement_list[2].position);
  1033. }
  1034. // Make non_primary_ids[1] primary.
  1035. window_tree_host_manager->SetPrimaryDisplayId(non_primary_ids[1]);
  1036. EXPECT_EQ(non_primary_ids[1],
  1037. display::Screen::GetScreen()->GetPrimaryDisplay().id());
  1038. // Expect that the layout will be changed to:
  1039. //
  1040. // +--------------------+ +--------------------+ +--------------------+
  1041. // | | | primary_id | | |
  1042. // | | +--------------------+ | |
  1043. // | | | | |
  1044. // | non_primary_ids[1] | V | non_primary_ids[2] |
  1045. // | (P) | +--------------------+ | |
  1046. // | |<--| non_primary_ids[0] |<--| |
  1047. // +--------------------+ +--------------------+ +--------------------+
  1048. {
  1049. const display::DisplayLayout& current_layout =
  1050. display_manager()->GetCurrentDisplayLayout();
  1051. EXPECT_EQ(non_primary_ids[1], current_layout.primary_id);
  1052. ASSERT_EQ(3u, current_layout.placement_list.size());
  1053. EXPECT_EQ(primary_id, current_layout.placement_list[0].display_id);
  1054. EXPECT_EQ(non_primary_ids[0],
  1055. current_layout.placement_list[0].parent_display_id);
  1056. EXPECT_EQ(display::DisplayPlacement::TOP,
  1057. current_layout.placement_list[0].position);
  1058. EXPECT_EQ(non_primary_ids[0], current_layout.placement_list[1].display_id);
  1059. EXPECT_EQ(non_primary_ids[1],
  1060. current_layout.placement_list[1].parent_display_id);
  1061. EXPECT_EQ(display::DisplayPlacement::RIGHT,
  1062. current_layout.placement_list[1].position);
  1063. EXPECT_EQ(non_primary_ids[2], current_layout.placement_list[2].display_id);
  1064. EXPECT_EQ(non_primary_ids[0],
  1065. current_layout.placement_list[2].parent_display_id);
  1066. EXPECT_EQ(display::DisplayPlacement::RIGHT,
  1067. current_layout.placement_list[2].position);
  1068. }
  1069. }
  1070. TEST_F(WindowTreeHostManagerTest, OverscanInsets) {
  1071. WindowTreeHostManager* window_tree_host_manager =
  1072. Shell::Get()->window_tree_host_manager();
  1073. TestEventHandler event_handler;
  1074. Shell::Get()->AddPreTargetHandler(&event_handler);
  1075. UpdateDisplay("120x200,300x400*2");
  1076. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1077. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1078. window_tree_host_manager->SetOverscanInsets(
  1079. display1.id(), gfx::Insets::TLBR(10, 15, 20, 25));
  1080. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  1081. EXPECT_EQ(gfx::Rect(0, 0, 80, 170), root_windows[0]->bounds());
  1082. EXPECT_EQ(gfx::Size(150, 200), root_windows[1]->bounds().size());
  1083. EXPECT_EQ(gfx::Rect(80, 0, 150, 200),
  1084. display_manager_test.GetSecondaryDisplay().bounds());
  1085. ui::test::EventGenerator generator(root_windows[0]);
  1086. generator.MoveMouseToInHost(20, 25);
  1087. EXPECT_EQ(gfx::Point(5, 15), event_handler.GetLocationAndReset());
  1088. window_tree_host_manager->SetOverscanInsets(display1.id(), gfx::Insets());
  1089. EXPECT_EQ(gfx::Rect(0, 0, 120, 200), root_windows[0]->bounds());
  1090. EXPECT_EQ(gfx::Rect(120, 0, 150, 200),
  1091. display_manager_test.GetSecondaryDisplay().bounds());
  1092. generator.MoveMouseToInHost(30, 20);
  1093. EXPECT_EQ(gfx::Point(30, 20), event_handler.GetLocationAndReset());
  1094. // Make sure the root window transformer uses correct scale
  1095. // factor when swapping display. Test crbug.com/253690.
  1096. UpdateDisplay("400x300*2,600x400/o");
  1097. root_windows = Shell::GetAllRootWindows();
  1098. gfx::Point point;
  1099. Shell::GetAllRootWindows()[1]->GetHost()->GetRootTransform().TransformPoint(
  1100. &point);
  1101. EXPECT_EQ(gfx::Point(15, 10), point);
  1102. SwapPrimaryDisplay();
  1103. point.SetPoint(0, 0);
  1104. Shell::GetAllRootWindows()[1]->GetHost()->GetRootTransform().TransformPoint(
  1105. &point);
  1106. EXPECT_EQ(gfx::Point(15, 10), point);
  1107. Shell::Get()->RemovePreTargetHandler(&event_handler);
  1108. }
  1109. TEST_F(WindowTreeHostManagerTest, Rotate) {
  1110. TestEventHandler event_handler;
  1111. Shell::Get()->AddPreTargetHandler(&event_handler);
  1112. UpdateDisplay("120x200,300x400*2");
  1113. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  1114. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1115. int64_t display2_id = display_manager_test.GetSecondaryDisplay().id();
  1116. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1117. ui::test::EventGenerator generator1(root_windows[0]);
  1118. TestObserver observer;
  1119. EXPECT_EQ(gfx::Size(120, 200), root_windows[0]->bounds().size());
  1120. EXPECT_EQ(gfx::Size(150, 200), root_windows[1]->bounds().size());
  1121. EXPECT_EQ(gfx::Rect(120, 0, 150, 200),
  1122. display_manager_test.GetSecondaryDisplay().bounds());
  1123. generator1.MoveMouseToInHost(50, 40);
  1124. EXPECT_EQ(gfx::Point(50, 40), event_handler.GetLocationAndReset());
  1125. EXPECT_EQ(display::Display::ROTATE_0,
  1126. GetActiveDisplayRotation(display1.id()));
  1127. EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
  1128. EXPECT_EQ(0, observer.GetRotationChangedCountAndReset());
  1129. display_manager()->SetDisplayRotation(
  1130. display1.id(), display::Display::ROTATE_90,
  1131. display::Display::RotationSource::ACTIVE);
  1132. EXPECT_EQ(gfx::Size(200, 120), root_windows[0]->bounds().size());
  1133. EXPECT_EQ(gfx::Size(150, 200), root_windows[1]->bounds().size());
  1134. EXPECT_EQ(gfx::Rect(200, 0, 150, 200),
  1135. display_manager_test.GetSecondaryDisplay().bounds());
  1136. generator1.MoveMouseToInHost(50, 40);
  1137. EXPECT_EQ(gfx::Point(40, 70), event_handler.GetLocationAndReset());
  1138. EXPECT_EQ(display::Display::ROTATE_90,
  1139. GetActiveDisplayRotation(display1.id()));
  1140. EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
  1141. EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
  1142. display_manager()->SetLayoutForCurrentDisplays(
  1143. display::test::CreateDisplayLayout(
  1144. display_manager(), display::DisplayPlacement::BOTTOM, 50));
  1145. EXPECT_EQ(gfx::Rect(50, 120, 150, 200),
  1146. display_manager_test.GetSecondaryDisplay().bounds());
  1147. display_manager()->SetDisplayRotation(
  1148. display2_id, display::Display::ROTATE_270,
  1149. display::Display::RotationSource::ACTIVE);
  1150. EXPECT_EQ(gfx::Size(200, 120), root_windows[0]->bounds().size());
  1151. EXPECT_EQ(gfx::Size(200, 150), root_windows[1]->bounds().size());
  1152. EXPECT_EQ(gfx::Rect(50, 120, 200, 150),
  1153. display_manager_test.GetSecondaryDisplay().bounds());
  1154. EXPECT_EQ(display::Display::ROTATE_90,
  1155. GetActiveDisplayRotation(display1.id()));
  1156. EXPECT_EQ(display::Display::ROTATE_270,
  1157. GetActiveDisplayRotation(display2_id));
  1158. EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
  1159. ui::test::EventGenerator generator2(root_windows[1]);
  1160. generator2.MoveMouseToInHost(50, 40);
  1161. EXPECT_EQ(gfx::Point(180, 25), event_handler.GetLocationAndReset());
  1162. display_manager()->SetDisplayRotation(
  1163. display1.id(), display::Display::ROTATE_180,
  1164. display::Display::RotationSource::ACTIVE);
  1165. EXPECT_EQ(gfx::Size(120, 200), root_windows[0]->bounds().size());
  1166. EXPECT_EQ(gfx::Size(200, 150), root_windows[1]->bounds().size());
  1167. // Display must share at least 100, so the x's offset becomes 20.
  1168. EXPECT_EQ(gfx::Rect(20, 200, 200, 150),
  1169. display_manager_test.GetSecondaryDisplay().bounds());
  1170. EXPECT_EQ(display::Display::ROTATE_180,
  1171. GetActiveDisplayRotation(display1.id()));
  1172. EXPECT_EQ(display::Display::ROTATE_270,
  1173. GetActiveDisplayRotation(display2_id));
  1174. EXPECT_EQ(1, observer.GetRotationChangedCountAndReset());
  1175. generator1.MoveMouseToInHost(50, 40);
  1176. EXPECT_EQ(gfx::Point(70, 160), event_handler.GetLocationAndReset());
  1177. Shell::Get()->RemovePreTargetHandler(&event_handler);
  1178. }
  1179. TEST_F(WindowTreeHostManagerTest, ScaleRootWindow) {
  1180. TestEventHandler event_handler;
  1181. Shell::Get()->AddPreTargetHandler(&event_handler);
  1182. UpdateDisplay("600x400*1.6,500x300");
  1183. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1184. display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
  1185. display1.id());
  1186. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  1187. display::Display display2 = display_manager_test.GetSecondaryDisplay();
  1188. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1189. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), display1.bounds());
  1190. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), root_windows[0]->bounds());
  1191. EXPECT_EQ(gfx::Rect(375, 0, 500, 300), display2.bounds());
  1192. EXPECT_FLOAT_EQ(1.0f, GetStoredZoomScale(display1.id()));
  1193. EXPECT_FLOAT_EQ(1.0f, GetStoredZoomScale(display2.id()));
  1194. ui::test::EventGenerator generator(root_windows[0]);
  1195. generator.MoveMouseToInHost(599, 200);
  1196. EXPECT_EQ(gfx::Point(374, 125), event_handler.GetLocationAndReset());
  1197. display_manager()->UpdateZoomFactor(display1.id(), 1.f / 1.2f);
  1198. display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1199. display2 = display_manager_test.GetSecondaryDisplay();
  1200. EXPECT_EQ(gfx::Rect(0, 0, 450, 300), display1.bounds());
  1201. EXPECT_EQ(gfx::Rect(0, 0, 450, 300), root_windows[0]->bounds());
  1202. EXPECT_EQ(gfx::Rect(450, 0, 500, 300), display2.bounds());
  1203. EXPECT_FLOAT_EQ(1.f / 1.2f, GetStoredZoomScale(display1.id()));
  1204. EXPECT_FLOAT_EQ(1.0f, GetStoredZoomScale(display2.id()));
  1205. Shell::Get()->RemovePreTargetHandler(&event_handler);
  1206. }
  1207. TEST_F(WindowTreeHostManagerTest, TouchScale) {
  1208. TestEventHandler event_handler;
  1209. Shell::Get()->AddPreTargetHandler(&event_handler);
  1210. UpdateDisplay("300x200*2");
  1211. display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
  1212. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1213. aura::Window* root_window = root_windows[0];
  1214. ui::test::EventGenerator generator(root_window);
  1215. generator.PressMoveAndReleaseTouchTo(50, 50);
  1216. // Default test touches have radius_x/y = 1.0, with device scale
  1217. // factor = 2, the scaled radius_x/y should be 0.5.
  1218. EXPECT_EQ(0.5, event_handler.touch_radius_x());
  1219. EXPECT_EQ(0.5, event_handler.touch_radius_y());
  1220. generator.ScrollSequence(gfx::Point(0, 0), base::Milliseconds(100), 10.0, 1.0,
  1221. 5, 1);
  1222. // ordinal_offset is invariant to the device scale factor.
  1223. EXPECT_EQ(event_handler.scroll_x_offset(),
  1224. event_handler.scroll_x_offset_ordinal());
  1225. EXPECT_EQ(event_handler.scroll_y_offset(),
  1226. event_handler.scroll_y_offset_ordinal());
  1227. Shell::Get()->RemovePreTargetHandler(&event_handler);
  1228. }
  1229. TEST_F(WindowTreeHostManagerTest, ConvertHostToRootCoords) {
  1230. TestEventHandler event_handler;
  1231. Shell::Get()->AddPreTargetHandler(&event_handler);
  1232. UpdateDisplay("600x400*2/r@0.8");
  1233. display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1234. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1235. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), display1.bounds());
  1236. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), root_windows[0]->bounds());
  1237. EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
  1238. ui::test::EventGenerator generator(root_windows[0]);
  1239. generator.MoveMouseToInHost(0, 0);
  1240. // The mouse location must be inside the root bounds in dp.
  1241. EXPECT_EQ(gfx::Point(0, 374), event_handler.GetLocationAndReset());
  1242. generator.MoveMouseToInHost(599, 0);
  1243. EXPECT_EQ(gfx::Point(0, 0), event_handler.GetLocationAndReset());
  1244. generator.MoveMouseToInHost(599, 399);
  1245. EXPECT_EQ(gfx::Point(249, 0), event_handler.GetLocationAndReset());
  1246. generator.MoveMouseToInHost(0, 399);
  1247. EXPECT_EQ(gfx::Point(249, 374), event_handler.GetLocationAndReset());
  1248. UpdateDisplay("600x400*2/u@0.8");
  1249. display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1250. root_windows = Shell::GetAllRootWindows();
  1251. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), display1.bounds());
  1252. EXPECT_EQ(gfx::Rect(0, 0, 375, 250), root_windows[0]->bounds());
  1253. EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
  1254. generator.MoveMouseToInHost(0, 0);
  1255. EXPECT_EQ(gfx::Point(374, 249), event_handler.GetLocationAndReset());
  1256. generator.MoveMouseToInHost(599, 0);
  1257. EXPECT_EQ(gfx::Point(0, 249), event_handler.GetLocationAndReset());
  1258. generator.MoveMouseToInHost(599, 399);
  1259. EXPECT_EQ(gfx::Point(0, 0), event_handler.GetLocationAndReset());
  1260. generator.MoveMouseToInHost(0, 399);
  1261. EXPECT_EQ(gfx::Point(374, 0), event_handler.GetLocationAndReset());
  1262. UpdateDisplay("600x400*2/l@0.8");
  1263. display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
  1264. root_windows = Shell::GetAllRootWindows();
  1265. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), display1.bounds());
  1266. EXPECT_EQ(gfx::Rect(0, 0, 250, 375), root_windows[0]->bounds());
  1267. EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
  1268. generator.MoveMouseToInHost(0, 0);
  1269. EXPECT_EQ(gfx::Point(249, 0), event_handler.GetLocationAndReset());
  1270. generator.MoveMouseToInHost(599, 0);
  1271. EXPECT_EQ(gfx::Point(249, 374), event_handler.GetLocationAndReset());
  1272. generator.MoveMouseToInHost(599, 399);
  1273. EXPECT_EQ(gfx::Point(0, 374), event_handler.GetLocationAndReset());
  1274. generator.MoveMouseToInHost(0, 399);
  1275. EXPECT_EQ(gfx::Point(0, 0), event_handler.GetLocationAndReset());
  1276. Shell::Get()->RemovePreTargetHandler(&event_handler);
  1277. }
  1278. // Make sure that the compositor based mirroring can switch
  1279. // from/to dock mode.
  1280. TEST_F(WindowTreeHostManagerTest, DockToSingle) {
  1281. const int64_t internal_id = 1;
  1282. const display::ManagedDisplayInfo internal_display_info =
  1283. CreateDisplayInfo(internal_id, 0, display::Display::ROTATE_0);
  1284. const display::ManagedDisplayInfo external_display_info =
  1285. CreateDisplayInfo(2, 1, display::Display::ROTATE_90);
  1286. std::vector<display::ManagedDisplayInfo> display_info_list;
  1287. // Extended
  1288. display_info_list.push_back(internal_display_info);
  1289. display_info_list.push_back(external_display_info);
  1290. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1291. const int64_t internal_display_id =
  1292. display::test::DisplayManagerTestApi(display_manager())
  1293. .SetFirstDisplayAsInternalDisplay();
  1294. EXPECT_EQ(internal_id, internal_display_id);
  1295. EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  1296. // Dock mode.
  1297. display_info_list.clear();
  1298. display_info_list.push_back(external_display_info);
  1299. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1300. EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  1301. EXPECT_FALSE(Shell::GetPrimaryRootWindow()
  1302. ->GetHost()
  1303. ->GetRootTransform()
  1304. .IsIdentityOrIntegerTranslation());
  1305. // Switch to single mode and make sure the transform is the one
  1306. // for the internal display.
  1307. display_info_list.clear();
  1308. display_info_list.push_back(internal_display_info);
  1309. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1310. EXPECT_TRUE(Shell::GetPrimaryRootWindow()
  1311. ->GetHost()
  1312. ->GetRootTransform()
  1313. .IsIdentityOrIntegerTranslation());
  1314. }
  1315. // Tests if switching two displays at the same time while the primary display
  1316. // is swapped should not cause a crash. (crbug.com/426292)
  1317. TEST_F(WindowTreeHostManagerTest, ReplaceSwappedPrimary) {
  1318. const display::ManagedDisplayInfo first_display_info =
  1319. CreateDisplayInfo(10, 0, display::Display::ROTATE_0);
  1320. const display::ManagedDisplayInfo second_display_info =
  1321. CreateDisplayInfo(11, 1, display::Display::ROTATE_0);
  1322. std::vector<display::ManagedDisplayInfo> display_info_list;
  1323. // Extended
  1324. display_info_list.push_back(first_display_info);
  1325. display_info_list.push_back(second_display_info);
  1326. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1327. SwapPrimaryDisplay();
  1328. EXPECT_EQ(11, display::Screen::GetScreen()->GetPrimaryDisplay().id());
  1329. display_info_list.clear();
  1330. const display::ManagedDisplayInfo new_first_display_info =
  1331. CreateDisplayInfo(20, 0, display::Display::ROTATE_0);
  1332. const display::ManagedDisplayInfo new_second_display_info =
  1333. CreateDisplayInfo(21, 1, display::Display::ROTATE_0);
  1334. display_info_list.push_back(new_first_display_info);
  1335. display_info_list.push_back(new_second_display_info);
  1336. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1337. EXPECT_EQ(20, display::Screen::GetScreen()->GetPrimaryDisplay().id());
  1338. }
  1339. namespace {
  1340. class RootWindowTestObserver : public aura::WindowObserver {
  1341. public:
  1342. RootWindowTestObserver() = default;
  1343. RootWindowTestObserver(const RootWindowTestObserver&) = delete;
  1344. RootWindowTestObserver& operator=(const RootWindowTestObserver&) = delete;
  1345. ~RootWindowTestObserver() override = default;
  1346. void OnWindowBoundsChanged(aura::Window* window,
  1347. const gfx::Rect& old_bounds,
  1348. const gfx::Rect& new_bounds,
  1349. ui::PropertyChangeReason reason) override {
  1350. shelf_display_bounds_ = screen_util::GetDisplayBoundsWithShelf(window);
  1351. }
  1352. // Returns the shelf display bounds, in screen coordinates.
  1353. const gfx::Rect& shelf_display_bounds() const {
  1354. return shelf_display_bounds_;
  1355. }
  1356. private:
  1357. gfx::Rect shelf_display_bounds_;
  1358. };
  1359. } // namespace
  1360. // Make sure that GetDisplayBoundsWithShelf returns the correct bounds
  1361. // when the primary display gets replaced in one of the following scenarios:
  1362. // 1) Two displays connected: a) b)
  1363. // 2) both are disconnected and new one with the same size as b) is connected
  1364. // in one configuration event.
  1365. // See crbug.com/547280.
  1366. TEST_F(WindowTreeHostManagerTest, ReplacePrimary) {
  1367. display::ManagedDisplayInfo first_display_info =
  1368. CreateDisplayInfo(10, 0, display::Display::ROTATE_0);
  1369. first_display_info.SetBounds(gfx::Rect(0, 0, 400, 300));
  1370. const display::ManagedDisplayInfo second_display_info =
  1371. CreateDisplayInfo(11, 500, display::Display::ROTATE_0);
  1372. std::vector<display::ManagedDisplayInfo> display_info_list;
  1373. // Extended
  1374. display_info_list.push_back(first_display_info);
  1375. display_info_list.push_back(second_display_info);
  1376. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1377. aura::Window* primary_root = Shell::GetAllRootWindows()[0];
  1378. int64_t new_display_id = 20;
  1379. RootWindowTestObserver test_observer;
  1380. primary_root->AddObserver(&test_observer);
  1381. display_info_list.clear();
  1382. const display::ManagedDisplayInfo new_first_display_info =
  1383. CreateDisplayInfo(new_display_id, 0, display::Display::ROTATE_0);
  1384. display_info_list.push_back(new_first_display_info);
  1385. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1386. // The shelf is now on the second display.
  1387. EXPECT_EQ(gfx::Rect(400, 0, 600, 500), test_observer.shelf_display_bounds());
  1388. primary_root->RemoveObserver(&test_observer);
  1389. }
  1390. TEST_F(WindowTreeHostManagerTest, UpdateMouseLocationAfterDisplayChange) {
  1391. UpdateDisplay("300x200,400x300");
  1392. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1393. aura::Env* env = aura::Env::GetInstance();
  1394. ui::test::EventGenerator generator_on_2nd(root_windows[1]);
  1395. // Set the initial position.
  1396. generator_on_2nd.MoveMouseToInHost(150, 150);
  1397. EXPECT_EQ(gfx::Point(450, 150), env->last_mouse_location());
  1398. // A mouse pointer will stay in the 2nd display.
  1399. UpdateDisplay("400x300,300x200");
  1400. EXPECT_EQ(gfx::Point(550, 50), env->last_mouse_location());
  1401. // A mouse pointer will be outside of displays and move to the
  1402. // center of 2nd display.
  1403. UpdateDisplay("400x300,110x100");
  1404. EXPECT_EQ(gfx::Point(455, 50), env->last_mouse_location());
  1405. // 2nd display was disconnected, and the cursor is
  1406. // now in the 1st display.
  1407. UpdateDisplay("500x400");
  1408. EXPECT_EQ(gfx::Point(55, 350), env->last_mouse_location());
  1409. // 1st display's resolution has changed, and the mouse pointer is
  1410. // now outside. Move the mouse pointer to the center of 1st display.
  1411. UpdateDisplay("400x300");
  1412. EXPECT_EQ(gfx::Point(200, 150), env->last_mouse_location());
  1413. // Move the mouse pointer to the bottom of 1st display.
  1414. ui::test::EventGenerator generator_on_1st(root_windows[0]);
  1415. generator_on_1st.MoveMouseToInHost(150, 290);
  1416. EXPECT_EQ(gfx::Point(150, 290), env->last_mouse_location());
  1417. // The mouse pointer is now on 2nd display.
  1418. UpdateDisplay("300x280,300x200");
  1419. EXPECT_EQ(gfx::Point(450, 10), env->last_mouse_location());
  1420. }
  1421. TEST_F(WindowTreeHostManagerTest,
  1422. DontUpdateInvisibleCursorLocationAfterDisplayChange) {
  1423. UpdateDisplay("500x300");
  1424. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1425. aura::Env* env = aura::Env::GetInstance();
  1426. ui::test::EventGenerator generator(root_windows[0]);
  1427. // Logical cursor location is updated to keep the same physical location.
  1428. generator.MoveMouseToInHost(350, 150);
  1429. EXPECT_EQ(gfx::Point(350, 150), env->last_mouse_location());
  1430. UpdateDisplay("300x500/r");
  1431. EXPECT_EQ(gfx::Point(250, 150), env->last_mouse_location());
  1432. // Logical cursor location change shouldn't change when the cursor isn't
  1433. // visible.
  1434. UpdateDisplay("500x300");
  1435. generator.MoveMouseToInHost(350, 150);
  1436. EXPECT_EQ(gfx::Point(350, 150), env->last_mouse_location());
  1437. Shell::Get()->cursor_manager()->HideCursor();
  1438. UpdateDisplay("300x500/r");
  1439. EXPECT_EQ(gfx::Point(350, 150), env->last_mouse_location());
  1440. }
  1441. TEST_F(WindowTreeHostManagerTest,
  1442. UpdateMouseLocationAfterDisplayChange_2ndOnLeft) {
  1443. // Set the 2nd display on the left.
  1444. display::DisplayLayoutStore* layout_store = display_manager()->layout_store();
  1445. display::DisplayPlacement new_default(display::DisplayPlacement::LEFT, 0);
  1446. layout_store->SetDefaultDisplayPlacement(new_default);
  1447. UpdateDisplay("300x200,400x300");
  1448. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  1449. EXPECT_EQ(gfx::Rect(-400, 0, 400, 300),
  1450. display::test::DisplayManagerTestApi(display_manager())
  1451. .GetSecondaryDisplay()
  1452. .bounds());
  1453. aura::Env* env = aura::Env::GetInstance();
  1454. // Set the initial position.
  1455. root_windows[0]->MoveCursorTo(gfx::Point(-150, 250));
  1456. EXPECT_EQ(gfx::Point(-150, 250), env->last_mouse_location());
  1457. // A mouse pointer will stay in 2nd display.
  1458. UpdateDisplay("400x300,200x300");
  1459. EXPECT_EQ(gfx::Point(-100, 150), env->last_mouse_location());
  1460. // A mouse pointer will be outside of displays and move to the
  1461. // center of 2nd display.
  1462. UpdateDisplay("400x300,200x100");
  1463. EXPECT_EQ(gfx::Point(-100, 50), env->last_mouse_location());
  1464. // 2nd display was disconnected. Mouse pointer should move to
  1465. // 1st display.
  1466. UpdateDisplay("400x300");
  1467. EXPECT_EQ(gfx::Point(200, 150), env->last_mouse_location());
  1468. }
  1469. // Test that the cursor swaps displays and that its scale factor and rotation
  1470. // are updated when the primary display is swapped.
  1471. TEST_F(WindowTreeHostManagerTest,
  1472. UpdateMouseLocationAfterDisplayChange_SwapPrimary) {
  1473. UpdateDisplay("300x200,300x200*2/r");
  1474. aura::Env* env = aura::Env::GetInstance();
  1475. Shell* shell = Shell::Get();
  1476. WindowTreeHostManager* window_tree_host_manager =
  1477. shell->window_tree_host_manager();
  1478. auto* cursor_manager = shell->cursor_manager();
  1479. CursorManagerTestApi test_api;
  1480. window_tree_host_manager->GetPrimaryRootWindow()->MoveCursorTo(
  1481. gfx::Point(20, 50));
  1482. EXPECT_EQ(gfx::Point(20, 50), env->last_mouse_location());
  1483. EXPECT_EQ(1.0f, cursor_manager->GetCursor().image_scale_factor());
  1484. EXPECT_EQ(display::Display::ROTATE_0, test_api.GetCurrentCursorRotation());
  1485. SwapPrimaryDisplay();
  1486. EXPECT_EQ(gfx::Point(20, 50), env->last_mouse_location());
  1487. EXPECT_EQ(2.0f, cursor_manager->GetCursor().image_scale_factor());
  1488. EXPECT_EQ(display::Display::ROTATE_90, test_api.GetCurrentCursorRotation());
  1489. }
  1490. // Test that the cursor moves to the other display and that its scale factor
  1491. // and rotation are updated when the primary display is disconnected.
  1492. TEST_F(WindowTreeHostManagerTest,
  1493. UpdateMouseLocationAfterDisplayChange_PrimaryDisconnected) {
  1494. aura::Env* env = aura::Env::GetInstance();
  1495. Shell* shell = Shell::Get();
  1496. WindowTreeHostManager* window_tree_host_manager =
  1497. shell->window_tree_host_manager();
  1498. auto* cursor_manager = shell->cursor_manager();
  1499. CursorManagerTestApi test_api;
  1500. UpdateDisplay("400x300*2/r,300x200");
  1501. // Swap the primary display to make it possible to remove the primary display
  1502. // via UpdateDisplay().
  1503. SwapPrimaryDisplay();
  1504. int primary_display_id = window_tree_host_manager->GetPrimaryDisplayId();
  1505. window_tree_host_manager->GetPrimaryRootWindow()->MoveCursorTo(
  1506. gfx::Point(20, 50));
  1507. EXPECT_EQ(gfx::Point(20, 50), env->last_mouse_location());
  1508. EXPECT_EQ(1.0f, cursor_manager->GetCursor().image_scale_factor());
  1509. EXPECT_EQ(display::Display::ROTATE_0, test_api.GetCurrentCursorRotation());
  1510. UpdateDisplay("400x300*2/r");
  1511. ASSERT_NE(primary_display_id,
  1512. window_tree_host_manager->GetPrimaryDisplayId());
  1513. // Cursor should be centered on the remaining display.
  1514. EXPECT_EQ(gfx::Point(75, 100), env->last_mouse_location());
  1515. EXPECT_EQ(2.0f, cursor_manager->GetCursor().image_scale_factor());
  1516. EXPECT_EQ(display::Display::ROTATE_90, test_api.GetCurrentCursorRotation());
  1517. }
  1518. TEST_F(WindowTreeHostManagerTest,
  1519. UpdateNonVisibleMouseLocationAfterDisplayChange_PrimaryDisconnected) {
  1520. aura::Env* env = aura::Env::GetInstance();
  1521. Shell* shell = Shell::Get();
  1522. WindowTreeHostManager* window_tree_host_manager =
  1523. shell->window_tree_host_manager();
  1524. auto* cursor_manager = shell->cursor_manager();
  1525. CursorManagerTestApi test_api;
  1526. UpdateDisplay("400x300*2/r,300x200");
  1527. // Swap the primary display to make it possible to remove the primary display
  1528. // via UpdateDisplay().
  1529. SwapPrimaryDisplay();
  1530. int primary_display_id = window_tree_host_manager->GetPrimaryDisplayId();
  1531. gfx::Point cursor_location(20, 50);
  1532. window_tree_host_manager->GetPrimaryRootWindow()->MoveCursorTo(
  1533. cursor_location);
  1534. // Hide cursor before disconnecting the display.
  1535. cursor_manager->HideCursor();
  1536. EXPECT_EQ(cursor_location, env->last_mouse_location());
  1537. EXPECT_EQ(1.0f, cursor_manager->GetCursor().image_scale_factor());
  1538. EXPECT_EQ(display::Display::ROTATE_0, test_api.GetCurrentCursorRotation());
  1539. UpdateDisplay("400x300*2/r");
  1540. ASSERT_NE(primary_display_id,
  1541. window_tree_host_manager->GetPrimaryDisplayId());
  1542. // Show the mouse cursor before checking properties which should be as if the
  1543. // mouse cursor was never hidden.
  1544. cursor_manager->ShowCursor();
  1545. // The cursor will not be centered since it was hidden when the display list
  1546. // was updated.
  1547. EXPECT_EQ(gfx::Point(20, 50), env->last_mouse_location());
  1548. // The cursor scale and rotation should be updated.
  1549. EXPECT_EQ(2.0f, cursor_manager->GetCursor().image_scale_factor());
  1550. EXPECT_EQ(display::Display::ROTATE_90, test_api.GetCurrentCursorRotation());
  1551. }
  1552. // GetRootWindowForDisplayId() for removed display::Display during
  1553. // OnDisplayRemoved() should not cause crash. See http://crbug.com/415222
  1554. TEST_F(WindowTreeHostManagerTest,
  1555. GetRootWindowForDisplayIdDuringDisplayDisconnection) {
  1556. UpdateDisplay("400x300,300x200");
  1557. aura::Window* root2 =
  1558. Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
  1559. display::test::DisplayManagerTestApi(display_manager())
  1560. .GetSecondaryDisplay()
  1561. .id());
  1562. views::Widget* widget = views::Widget::CreateWindowWithContext(
  1563. nullptr, root2, gfx::Rect(350, 0, 100, 100));
  1564. views::View* view = new views::View();
  1565. widget->GetContentsView()->AddChildView(view);
  1566. view->SetBounds(0, 0, 100, 100);
  1567. widget->Show();
  1568. TestMouseWatcherListener listener;
  1569. views::MouseWatcher watcher(
  1570. std::make_unique<views::MouseWatcherViewHost>(view, gfx::Insets()),
  1571. &listener);
  1572. watcher.Start(root2);
  1573. ui::test::EventGenerator event_generator(
  1574. widget->GetNativeWindow()->GetRootWindow());
  1575. event_generator.MoveMouseToCenterOf(widget->GetNativeWindow());
  1576. UpdateDisplay("400x300");
  1577. watcher.Stop();
  1578. widget->CloseNow();
  1579. }
  1580. // Replicates the behavior of MouseWatcher MouseEvent handling that led to crash
  1581. // in https://crbug.com/1278429.
  1582. class RootWindowTestEventHandler : public ui::EventHandler {
  1583. public:
  1584. explicit RootWindowTestEventHandler() = default;
  1585. RootWindowTestEventHandler(const RootWindowTestEventHandler&) = delete;
  1586. RootWindowTestEventHandler& operator=(const RootWindowTestEventHandler&) =
  1587. delete;
  1588. ~RootWindowTestEventHandler() override = default;
  1589. private:
  1590. // ui::EventHandler overrides:
  1591. void OnMouseEvent(ui::MouseEvent* event) override {
  1592. // Crash happened when finding the display in
  1593. // |screen::GetDisplayNearestPoint()|, we got the display that was being
  1594. // removed and in turn got null root window from
  1595. // |window_util::GetRootWindowAt| since the root window was moved to the new
  1596. // primary display.
  1597. display::Screen::GetScreen()->GetWindowAtScreenPoint(
  1598. display::Screen::GetScreen()->GetCursorScreenPoint());
  1599. }
  1600. };
  1601. // Tests for the crash during the replacement of the primary display.
  1602. // See https://crbug.com/1278429.
  1603. TEST_F(WindowTreeHostManagerTest, GetActiveDisplayWhenReplacingPrimaryDisplay) {
  1604. // We observed a crash during handling of a MouseEvent.
  1605. UpdateDisplay("800x600");
  1606. aura::Window* root_window =
  1607. Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
  1608. GetPrimaryDisplay().id());
  1609. RootWindowTestEventHandler handler;
  1610. root_window->AddPreTargetHandler(&handler);
  1611. ui::test::EventGenerator generator(root_window);
  1612. // Move the cursor to a coordinate that is in the logical bounds of the older
  1613. // display[0,0 800x600] but not in the logical bounds[0,0 350x250] of the new
  1614. // display. The cursor coordinates also needs to be in the root window's
  1615. // bounds[0,0 700x500] attached to the new primary display.
  1616. generator.MoveMouseTo(400, 300);
  1617. // Replace the primary display with a newer display with a different device
  1618. // scale factor compared to original display.
  1619. display::ManagedDisplayInfo first_display_info =
  1620. CreateDisplayInfo(100, 0, display::Display::ROTATE_0);
  1621. first_display_info.SetBounds(gfx::Rect(0, 0, 700, 500));
  1622. first_display_info.set_device_scale_factor(2.0);
  1623. std::vector<display::ManagedDisplayInfo> display_info_list;
  1624. display_info_list.push_back(first_display_info);
  1625. display_manager()->OnNativeDisplaysChanged(display_info_list);
  1626. root_window->RemovePreTargetHandler(&handler);
  1627. }
  1628. TEST_F(WindowTreeHostManagerTest, KeyEventFromSecondaryDisplay) {
  1629. UpdateDisplay("400x300,300x200");
  1630. ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0);
  1631. ui::Event::DispatcherApi dispatcher_api(&key_event);
  1632. // Set the target to the second display. WindowTreeHostManager will end up
  1633. // targeting the primary display.
  1634. dispatcher_api.set_target(
  1635. Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
  1636. GetSecondaryDisplay().id()));
  1637. Shell::Get()->window_tree_host_manager()->DispatchKeyEventPostIME(&key_event);
  1638. // As long as nothing crashes, we're good.
  1639. }
  1640. } // namespace ash