extended_desktop_unittest.cc 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  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/public/cpp/shell_window_ids.h"
  5. #include "ash/root_window_controller.h"
  6. #include "ash/shell.h"
  7. #include "ash/system/status_area_widget.h"
  8. #include "ash/system/status_area_widget_test_helper.h"
  9. #include "ash/system/unified/unified_system_tray.h"
  10. #include "ash/test/ash_test_base.h"
  11. #include "ash/test/test_widget_builder.h"
  12. #include "ash/test/test_window_builder.h"
  13. #include "ash/wm/desks/desks_util.h"
  14. #include "ash/wm/window_properties.h"
  15. #include "ash/wm/window_util.h"
  16. #include "base/run_loop.h"
  17. #include "base/strings/string_util.h"
  18. #include "base/strings/utf_string_conversions.h"
  19. #include "ui/aura/client/capture_client.h"
  20. #include "ui/aura/client/focus_client.h"
  21. #include "ui/aura/test/test_windows.h"
  22. #include "ui/aura/test/window_test_api.h"
  23. #include "ui/aura/window.h"
  24. #include "ui/aura/window_event_dispatcher.h"
  25. #include "ui/base/cursor/cursor.h"
  26. #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
  27. #include "ui/display/display.h"
  28. #include "ui/display/display_layout.h"
  29. #include "ui/display/manager/display_manager.h"
  30. #include "ui/display/screen.h"
  31. #include "ui/events/event_handler.h"
  32. #include "ui/events/test/event_generator.h"
  33. #include "ui/views/controls/textfield/textfield.h"
  34. #include "ui/views/widget/widget.h"
  35. #include "ui/views/widget/widget_delegate.h"
  36. #include "ui/wm/core/window_util.h"
  37. #include "ui/wm/public/activation_client.h"
  38. namespace ash {
  39. namespace {
  40. void SetSecondaryDisplayLayout(display::DisplayPlacement::Position position) {
  41. std::unique_ptr<display::DisplayLayout> layout =
  42. Shell::Get()->display_manager()->GetCurrentDisplayLayout().Copy();
  43. layout->placement_list[0].position = position;
  44. Shell::Get()->display_manager()->SetLayoutForCurrentDisplays(
  45. std::move(layout));
  46. }
  47. // An event handler which moves the target window to the secondary root window
  48. // at pre-handle phase of a mouse release event.
  49. class MoveWindowByClickEventHandler : public ui::EventHandler {
  50. public:
  51. explicit MoveWindowByClickEventHandler(aura::Window* target)
  52. : target_(target) {}
  53. MoveWindowByClickEventHandler(const MoveWindowByClickEventHandler&) = delete;
  54. MoveWindowByClickEventHandler& operator=(
  55. const MoveWindowByClickEventHandler&) = delete;
  56. ~MoveWindowByClickEventHandler() override = default;
  57. private:
  58. // ui::EventHandler overrides:
  59. void OnMouseEvent(ui::MouseEvent* event) override {
  60. if (event->type() == ui::ET_MOUSE_RELEASED) {
  61. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  62. DCHECK_LT(1u, root_windows.size());
  63. root_windows[1]->AddChild(target_);
  64. }
  65. }
  66. aura::Window* target_;
  67. };
  68. // An event handler which records the event's locations.
  69. class EventLocationRecordingEventHandler : public ui::EventHandler {
  70. public:
  71. EventLocationRecordingEventHandler() { Reset(); }
  72. EventLocationRecordingEventHandler(
  73. const EventLocationRecordingEventHandler&) = delete;
  74. EventLocationRecordingEventHandler& operator=(
  75. const EventLocationRecordingEventHandler&) = delete;
  76. ~EventLocationRecordingEventHandler() override = default;
  77. // |location_| is relative to the target window.
  78. std::string GetLocation() const { return location_.ToString(); }
  79. // |root_location_| is relative to the display where the event started.
  80. std::string GetRootLocation() const { return root_location_.ToString(); }
  81. void Reset() {
  82. location_.SetPoint(-999, -999);
  83. root_location_.SetPoint(-999, -999);
  84. }
  85. private:
  86. // ui::EventHandler overrides:
  87. void OnMouseEvent(ui::MouseEvent* event) override {
  88. if (event->type() == ui::ET_MOUSE_MOVED ||
  89. event->type() == ui::ET_MOUSE_DRAGGED) {
  90. location_ = event->location();
  91. root_location_ = event->root_location();
  92. }
  93. }
  94. gfx::Point root_location_;
  95. gfx::Point location_;
  96. };
  97. class EventLocationHandler : public ui::EventHandler {
  98. public:
  99. EventLocationHandler() = default;
  100. EventLocationHandler(const EventLocationHandler&) = delete;
  101. EventLocationHandler& operator=(const EventLocationHandler&) = delete;
  102. ~EventLocationHandler() override = default;
  103. const gfx::Point& press_location() const { return press_location_; }
  104. const gfx::Point& release_location() const { return release_location_; }
  105. private:
  106. // ui::EventHandler:
  107. void OnMouseEvent(ui::MouseEvent* event) override {
  108. if (event->type() == ui::ET_MOUSE_PRESSED)
  109. press_location_ = event->location();
  110. else if (event->type() == ui::ET_MOUSE_RELEASED)
  111. release_location_ = event->location();
  112. }
  113. gfx::Point press_location_;
  114. gfx::Point release_location_;
  115. };
  116. } // namespace
  117. class ExtendedDesktopTest : public AshTestBase {
  118. public:
  119. ExtendedDesktopTest() = default;
  120. ExtendedDesktopTest(const ExtendedDesktopTest&) = delete;
  121. ExtendedDesktopTest& operator=(const ExtendedDesktopTest&) = delete;
  122. ~ExtendedDesktopTest() override = default;
  123. void SetUp() override {
  124. AshTestBase::SetUp();
  125. // Shell hides the cursor by default; show it for these tests.
  126. Shell::Get()->cursor_manager()->ShowCursor();
  127. }
  128. views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
  129. return TestWidgetBuilder()
  130. .SetBounds(bounds)
  131. .SetContext(GetContext())
  132. .BuildOwnedByNativeWidget();
  133. }
  134. protected:
  135. bool IsBubbleShown() {
  136. return GetPrimaryUnifiedSystemTray()->IsBubbleShown();
  137. }
  138. gfx::Rect GetSystemTrayBoundsInScreen() {
  139. return GetPrimaryUnifiedSystemTray()->GetBoundsInScreen();
  140. }
  141. };
  142. // Test conditions that root windows in extended desktop mode must satisfy.
  143. TEST_F(ExtendedDesktopTest, Basic) {
  144. UpdateDisplay("1000x600,600x400");
  145. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  146. // All root windows must have a root window controller.
  147. ASSERT_EQ(2U, root_windows.size());
  148. EXPECT_TRUE(RootWindowController::ForWindow(root_windows[0]));
  149. EXPECT_TRUE(RootWindowController::ForWindow(root_windows[1]));
  150. // Make sure root windows share the same controllers.
  151. EXPECT_EQ(aura::client::GetFocusClient(root_windows[0]),
  152. aura::client::GetFocusClient(root_windows[1]));
  153. EXPECT_EQ(::wm::GetActivationClient(root_windows[0]),
  154. ::wm::GetActivationClient(root_windows[1]));
  155. EXPECT_EQ(aura::client::GetCaptureClient(root_windows[0]),
  156. aura::client::GetCaptureClient(root_windows[1]));
  157. }
  158. TEST_F(ExtendedDesktopTest, Activation) {
  159. UpdateDisplay("1000x600,600x400");
  160. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  161. views::Widget* widget_on_1st = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
  162. views::Widget* widget_on_2nd =
  163. CreateTestWidget(gfx::Rect(1200, 10, 100, 100));
  164. EXPECT_EQ(root_windows[0], widget_on_1st->GetNativeView()->GetRootWindow());
  165. EXPECT_EQ(root_windows[1], widget_on_2nd->GetNativeView()->GetRootWindow());
  166. EXPECT_EQ(widget_on_2nd->GetNativeView(),
  167. aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow());
  168. EXPECT_TRUE(wm::IsActiveWindow(widget_on_2nd->GetNativeView()));
  169. ui::test::EventGenerator* event_generator = GetEventGenerator();
  170. // Clicking a window changes the active window and active root window.
  171. event_generator->MoveMouseToCenterOf(widget_on_1st->GetNativeView());
  172. event_generator->ClickLeftButton();
  173. EXPECT_EQ(widget_on_1st->GetNativeView(),
  174. aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow());
  175. EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView()));
  176. event_generator->MoveMouseToCenterOf(widget_on_2nd->GetNativeView());
  177. event_generator->ClickLeftButton();
  178. EXPECT_EQ(widget_on_2nd->GetNativeView(),
  179. aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow());
  180. EXPECT_TRUE(wm::IsActiveWindow(widget_on_2nd->GetNativeView()));
  181. }
  182. TEST_F(ExtendedDesktopTest, SystemModal) {
  183. UpdateDisplay("1000x600,600x400");
  184. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  185. views::Widget* widget_on_1st = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
  186. EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView()));
  187. EXPECT_EQ(root_windows[0], widget_on_1st->GetNativeView()->GetRootWindow());
  188. EXPECT_EQ(root_windows[0], Shell::GetRootWindowForNewWindows());
  189. // Open system modal. Make sure it's on 2nd root window and active.
  190. auto delegate = std::make_unique<views::WidgetDelegateView>();
  191. delegate->SetModalType(ui::MODAL_TYPE_SYSTEM);
  192. views::Widget* modal_widget = views::Widget::CreateWindowWithContext(
  193. delegate.release(), GetContext(), gfx::Rect(1200, 100, 100, 100));
  194. modal_widget->Show();
  195. EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView()));
  196. EXPECT_EQ(root_windows[1], modal_widget->GetNativeView()->GetRootWindow());
  197. EXPECT_EQ(root_windows[1], Shell::GetRootWindowForNewWindows());
  198. ui::test::EventGenerator* event_generator = GetEventGenerator();
  199. // Clicking a widget on widget_on_1st display should not change activation.
  200. event_generator->MoveMouseToCenterOf(widget_on_1st->GetNativeView());
  201. event_generator->ClickLeftButton();
  202. EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView()));
  203. EXPECT_EQ(root_windows[1], Shell::GetRootWindowForNewWindows());
  204. // Close system modal and so clicking a widget should work now.
  205. modal_widget->Close();
  206. event_generator->MoveMouseToCenterOf(widget_on_1st->GetNativeView());
  207. event_generator->ClickLeftButton();
  208. EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView()));
  209. EXPECT_EQ(root_windows[0], Shell::GetRootWindowForNewWindows());
  210. }
  211. TEST_F(ExtendedDesktopTest, TestCursor) {
  212. UpdateDisplay("1000x600,600x400");
  213. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  214. aura::WindowTreeHost* host0 = root_windows[0]->GetHost();
  215. aura::WindowTreeHost* host1 = root_windows[1]->GetHost();
  216. EXPECT_EQ(ui::mojom::CursorType::kPointer, host0->last_cursor().type());
  217. EXPECT_EQ(ui::mojom::CursorType::kNull, host1->last_cursor().type());
  218. Shell::Get()->cursor_manager()->SetCursor(ui::mojom::CursorType::kCopy);
  219. EXPECT_EQ(ui::mojom::CursorType::kCopy, host0->last_cursor().type());
  220. EXPECT_EQ(ui::mojom::CursorType::kCopy, host1->last_cursor().type());
  221. }
  222. TEST_F(ExtendedDesktopTest, TestCursorLocation) {
  223. UpdateDisplay("1000x600,600x400");
  224. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  225. aura::test::WindowTestApi root_window0_test_api(root_windows[0]);
  226. aura::test::WindowTestApi root_window1_test_api(root_windows[1]);
  227. root_windows[0]->MoveCursorTo(gfx::Point(10, 10));
  228. EXPECT_EQ("10,10",
  229. display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  230. EXPECT_TRUE(root_window0_test_api.ContainsMouse());
  231. EXPECT_FALSE(root_window1_test_api.ContainsMouse());
  232. root_windows[1]->MoveCursorTo(gfx::Point(10, 20));
  233. EXPECT_EQ("1010,20",
  234. display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  235. EXPECT_FALSE(root_window0_test_api.ContainsMouse());
  236. EXPECT_TRUE(root_window1_test_api.ContainsMouse());
  237. root_windows[0]->MoveCursorTo(gfx::Point(20, 10));
  238. EXPECT_EQ("20,10",
  239. display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  240. EXPECT_TRUE(root_window0_test_api.ContainsMouse());
  241. EXPECT_FALSE(root_window1_test_api.ContainsMouse());
  242. }
  243. TEST_F(ExtendedDesktopTest, GetRootWindowAt) {
  244. UpdateDisplay("700x500,600x500");
  245. SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT);
  246. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  247. using window_util::GetRootWindowAt;
  248. EXPECT_EQ(root_windows[1], GetRootWindowAt(gfx::Point(-400, 100)));
  249. EXPECT_EQ(root_windows[1], GetRootWindowAt(gfx::Point(-1, 100)));
  250. EXPECT_EQ(root_windows[0], GetRootWindowAt(gfx::Point(0, 300)));
  251. EXPECT_EQ(root_windows[0], GetRootWindowAt(gfx::Point(700, 300)));
  252. // Zero origin.
  253. EXPECT_EQ(root_windows[0], GetRootWindowAt(gfx::Point(0, 0)));
  254. // Out of range point should return the nearest root window
  255. EXPECT_EQ(root_windows[1], GetRootWindowAt(gfx::Point(-600, 0)));
  256. EXPECT_EQ(root_windows[0], GetRootWindowAt(gfx::Point(701, 100)));
  257. }
  258. TEST_F(ExtendedDesktopTest, GetRootWindowMatching) {
  259. UpdateDisplay("700x500,600x500");
  260. SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT);
  261. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  262. // Containing rect.
  263. using window_util::GetRootWindowMatching;
  264. EXPECT_EQ(root_windows[1],
  265. GetRootWindowMatching(gfx::Rect(-300, 10, 50, 50)));
  266. EXPECT_EQ(root_windows[0], GetRootWindowMatching(gfx::Rect(100, 10, 50, 50)));
  267. // Intersecting rect.
  268. EXPECT_EQ(root_windows[1],
  269. GetRootWindowMatching(gfx::Rect(-200, 0, 300, 300)));
  270. EXPECT_EQ(root_windows[0],
  271. GetRootWindowMatching(gfx::Rect(-100, 0, 300, 300)));
  272. // Zero origin.
  273. EXPECT_EQ(root_windows[0], GetRootWindowMatching(gfx::Rect(0, 0, 0, 0)));
  274. EXPECT_EQ(root_windows[0], GetRootWindowMatching(gfx::Rect(0, 0, 1, 1)));
  275. // Empty rect.
  276. EXPECT_EQ(root_windows[1], GetRootWindowMatching(gfx::Rect(-400, 100, 0, 0)));
  277. EXPECT_EQ(root_windows[0], GetRootWindowMatching(gfx::Rect(100, 100, 0, 0)));
  278. // Out of range rect should return the primary root window.
  279. EXPECT_EQ(root_windows[0],
  280. GetRootWindowMatching(gfx::Rect(-600, -300, 50, 50)));
  281. EXPECT_EQ(root_windows[0], GetRootWindowMatching(gfx::Rect(0, 1000, 50, 50)));
  282. }
  283. TEST_F(ExtendedDesktopTest, Capture) {
  284. // This test deals with input events but not visuals so don't throttle input
  285. // on visuals.
  286. aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false);
  287. UpdateDisplay("1000x600,600x400");
  288. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  289. aura::test::EventCountDelegate r1_d1;
  290. aura::test::EventCountDelegate r1_d2;
  291. aura::test::EventCountDelegate r2_d1;
  292. std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
  293. &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
  294. std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
  295. &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
  296. std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
  297. &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
  298. r1_w1->SetCapture();
  299. EXPECT_EQ(r1_w1.get(),
  300. aura::client::GetCaptureWindow(r2_w1->GetRootWindow()));
  301. ui::test::EventGenerator* generator = GetEventGenerator();
  302. generator->MoveMouseToCenterOf(r2_w1.get());
  303. // |r1_w1| will receive the events because it has capture.
  304. EXPECT_EQ("1 1 0", r1_d1.GetMouseMotionCountsAndReset());
  305. EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
  306. EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
  307. generator->ClickLeftButton();
  308. EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
  309. EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset());
  310. // The mouse is outside. On chromeos, the mouse is warped to the
  311. // dest root window, but it's not implemented on Win yet, so
  312. // no mouse move event on Win.
  313. EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset());
  314. EXPECT_EQ("1 1", r1_d1.GetMouseButtonCountsAndReset());
  315. generator->MoveMouseTo(15, 15);
  316. EXPECT_EQ("0 1 0", r1_d1.GetMouseMotionCountsAndReset());
  317. EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
  318. r1_w2->SetCapture();
  319. EXPECT_EQ(r1_w2.get(),
  320. aura::client::GetCaptureWindow(r2_w1->GetRootWindow()));
  321. generator->MoveMouseBy(10, 10);
  322. // |r1_w2| has the capture. So it will receive the mouse-move event.
  323. EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset());
  324. EXPECT_EQ("0 1 0", r1_d2.GetMouseMotionCountsAndReset());
  325. EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
  326. generator->ClickLeftButton();
  327. EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
  328. EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset());
  329. EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
  330. EXPECT_EQ("1 1", r1_d2.GetMouseButtonCountsAndReset());
  331. r1_w2->ReleaseCapture();
  332. EXPECT_EQ(nullptr, aura::client::GetCaptureWindow(r2_w1->GetRootWindow()));
  333. generator->MoveMouseToCenterOf(r2_w1.get());
  334. generator->ClickLeftButton();
  335. EXPECT_EQ("1 1 0", r2_d1.GetMouseMotionCountsAndReset());
  336. EXPECT_EQ("1 1", r2_d1.GetMouseButtonCountsAndReset());
  337. // Make sure the mouse_moved_handler_ is properly reset.
  338. EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
  339. EXPECT_EQ("0 0", r1_d2.GetMouseButtonCountsAndReset());
  340. }
  341. TEST_F(ExtendedDesktopTest, CaptureEventLocation) {
  342. UpdateDisplay("1000x600,600x400");
  343. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  344. aura::test::EventCountDelegate r1_d1;
  345. aura::test::EventCountDelegate r1_d2;
  346. aura::test::EventCountDelegate r2_d1;
  347. std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
  348. &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
  349. std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
  350. &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
  351. std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
  352. &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
  353. r1_w1->SetCapture();
  354. ui::test::EventGenerator* generator = GetEventGenerator();
  355. generator->MoveMouseToCenterOf(r2_w1.get());
  356. EXPECT_EQ(gfx::Point(1060, 60).ToString(),
  357. generator->current_screen_location().ToString());
  358. EventLocationHandler location_handler;
  359. r1_w1->AddPreTargetHandler(&location_handler);
  360. generator->ClickLeftButton();
  361. r1_w1->RemovePreTargetHandler(&location_handler);
  362. EXPECT_EQ(gfx::Point(1050, 50).ToString(),
  363. location_handler.press_location().ToString());
  364. EXPECT_EQ(gfx::Point(1050, 50).ToString(),
  365. location_handler.release_location().ToString());
  366. }
  367. TEST_F(ExtendedDesktopTest, CaptureEventLocationHighDPI) {
  368. UpdateDisplay("1000x600*2,600x400");
  369. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  370. aura::test::EventCountDelegate r1_d1;
  371. aura::test::EventCountDelegate r1_d2;
  372. aura::test::EventCountDelegate r2_d1;
  373. std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
  374. &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
  375. std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
  376. &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
  377. std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
  378. &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
  379. r1_w1->SetCapture();
  380. ui::test::EventGenerator* generator = GetEventGenerator();
  381. generator->MoveMouseToCenterOf(r2_w1.get());
  382. EXPECT_EQ(gfx::Point(560, 60).ToString(),
  383. generator->current_screen_location().ToString());
  384. EventLocationHandler location_handler;
  385. r1_w1->AddPreTargetHandler(&location_handler);
  386. generator->ClickLeftButton();
  387. r1_w1->RemovePreTargetHandler(&location_handler);
  388. EXPECT_EQ(gfx::Point(550, 50).ToString(),
  389. location_handler.press_location().ToString());
  390. EXPECT_EQ(gfx::Point(550, 50).ToString(),
  391. location_handler.release_location().ToString());
  392. }
  393. TEST_F(ExtendedDesktopTest, CaptureEventLocationHighDPI_2) {
  394. UpdateDisplay("1000x600,600x400*2");
  395. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  396. aura::test::EventCountDelegate r1_d1;
  397. aura::test::EventCountDelegate r1_d2;
  398. aura::test::EventCountDelegate r2_d1;
  399. std::unique_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
  400. &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
  401. std::unique_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
  402. &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
  403. std::unique_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
  404. &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
  405. r1_w1->SetCapture();
  406. ui::test::EventGenerator* generator = GetEventGenerator();
  407. generator->MoveMouseToCenterOf(r2_w1.get());
  408. EXPECT_EQ(gfx::Point(1060, 60).ToString(),
  409. generator->current_screen_location().ToString());
  410. EventLocationHandler location_handler;
  411. r1_w1->AddPreTargetHandler(&location_handler);
  412. generator->ClickLeftButton();
  413. r1_w1->RemovePreTargetHandler(&location_handler);
  414. // Event-generator dispatches the event in the primary root-window's coord
  415. // space. Since the location is (1060, 60), it goes to the secondary
  416. // root-window as (30, 30) since the secondary root-window has a device scale
  417. // factor of 2.
  418. EXPECT_EQ(gfx::Point(1020, 20).ToString(),
  419. location_handler.press_location().ToString());
  420. EXPECT_EQ(gfx::Point(1020, 20).ToString(),
  421. location_handler.release_location().ToString());
  422. }
  423. TEST_F(ExtendedDesktopTest, MoveWindow) {
  424. UpdateDisplay("1000x600,600x400");
  425. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  426. views::Widget* d1 = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
  427. EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
  428. d1->SetBounds(gfx::Rect(1010, 10, 100, 100));
  429. EXPECT_EQ("1010,10 100x100", d1->GetWindowBoundsInScreen().ToString());
  430. EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow());
  431. d1->SetBounds(gfx::Rect(10, 10, 100, 100));
  432. EXPECT_EQ("10,10 100x100", d1->GetWindowBoundsInScreen().ToString());
  433. EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
  434. // Make sure the bounds which doesn't fit to the root window
  435. // works correctly.
  436. d1->SetBounds(gfx::Rect(1560, 30, 100, 100));
  437. EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow());
  438. EXPECT_EQ("1560,30 100x100", d1->GetWindowBoundsInScreen().ToString());
  439. // Setting outside of root windows will be moved to primary root window.
  440. // TODO(oshima): This one probably should pick the closest root window.
  441. d1->SetBounds(gfx::Rect(200, 10, 100, 100));
  442. EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
  443. }
  444. // Verifies if the mouse event arrives to the window even when the window
  445. // moves to another root in a pre-target handler. See: crbug.com/157583
  446. TEST_F(ExtendedDesktopTest, MoveWindowByMouseClick) {
  447. UpdateDisplay("1000x600,600x400");
  448. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  449. aura::test::EventCountDelegate delegate;
  450. std::unique_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
  451. &delegate, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
  452. MoveWindowByClickEventHandler event_handler(window.get());
  453. window->AddPreTargetHandler(&event_handler);
  454. ui::test::EventGenerator* event_generator = GetEventGenerator();
  455. event_generator->MoveMouseToCenterOf(window.get());
  456. event_generator->ClickLeftButton();
  457. // Both mouse pressed and released arrive at the window and its delegate.
  458. EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
  459. // Also event_handler moves the window to another root at mouse release.
  460. EXPECT_EQ(root_windows[1], window->GetRootWindow());
  461. }
  462. TEST_F(ExtendedDesktopTest, MoveWindowToDisplay) {
  463. UpdateDisplay("1000x900,1000x900");
  464. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  465. display::Display display0 = display::Screen::GetScreen()->GetDisplayMatching(
  466. root_windows[0]->GetBoundsInScreen());
  467. display::Display display1 = display::Screen::GetScreen()->GetDisplayMatching(
  468. root_windows[1]->GetBoundsInScreen());
  469. EXPECT_NE(display0.id(), display1.id());
  470. views::Widget* d1 = CreateTestWidget(gfx::Rect(10, 10, 1000, 100));
  471. EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
  472. // Move the window where the window spans both root windows. Since the second
  473. // parameter is |display1|, the window should be shown on the secondary root.
  474. d1->GetNativeWindow()->SetBoundsInScreen(gfx::Rect(500, 10, 1000, 100),
  475. display1);
  476. EXPECT_EQ("500,10 1000x100", d1->GetWindowBoundsInScreen().ToString());
  477. EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow());
  478. // Move to the primary root.
  479. d1->GetNativeWindow()->SetBoundsInScreen(gfx::Rect(500, 10, 1000, 100),
  480. display0);
  481. EXPECT_EQ("500,10 1000x100", d1->GetWindowBoundsInScreen().ToString());
  482. EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
  483. }
  484. TEST_F(ExtendedDesktopTest, MoveWindowWithTransient) {
  485. UpdateDisplay("1000x600,600x400");
  486. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  487. // Create and activate a normal window |w1|.
  488. aura::Window* w1 =
  489. CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 100, 100));
  490. wm::ActivateWindow(w1);
  491. // |w1_t1| is a transient child window of |w1|.
  492. std::unique_ptr<aura::Window> w1_t1 =
  493. ChildTestWindowBuilder(w1, gfx::Rect(50, 50, 50, 50),
  494. desks_util::GetActiveDeskContainerId())
  495. .Build();
  496. ::wm::AddTransientChild(w1, w1_t1.get());
  497. // |w1_t11| is a transient child window of transient child window |w1_t1|.
  498. std::unique_ptr<aura::Window> w1_t11 =
  499. ChildTestWindowBuilder(w1_t1.get(), gfx::Rect(2, 7, 35, 35),
  500. desks_util::GetActiveDeskContainerId())
  501. .Build();
  502. ::wm::AddTransientChild(w1_t1.get(), w1_t11.get());
  503. // |w11| is a non-transient child window of |w1|.
  504. std::unique_ptr<aura::Window> w11 =
  505. ChildTestWindowBuilder(w1, gfx::Rect(10, 10, 40, 40),
  506. desks_util::GetActiveDeskContainerId())
  507. .Build();
  508. // |w11_t1| is a transient child window of |w11|.
  509. std::unique_ptr<aura::Window> w11_t1 =
  510. ChildTestWindowBuilder(w11.get(), gfx::Rect(30, 10, 80, 80),
  511. desks_util::GetActiveDeskContainerId())
  512. .Build();
  513. ::wm::AddTransientChild(w11.get(), w11_t1.get());
  514. EXPECT_EQ(root_windows[0], w1->GetRootWindow());
  515. EXPECT_EQ(root_windows[0], w1_t1->GetRootWindow());
  516. EXPECT_EQ(root_windows[0], w1_t11->GetRootWindow());
  517. EXPECT_EQ(root_windows[0], w11->GetRootWindow());
  518. EXPECT_EQ(root_windows[0], w11_t1->GetRootWindow());
  519. EXPECT_EQ("10,10 100x100", w1->GetBoundsInScreen().ToString());
  520. EXPECT_EQ("60,60 50x50", w1_t1->GetBoundsInScreen().ToString());
  521. EXPECT_EQ("62,67 35x35", w1_t11->GetBoundsInScreen().ToString());
  522. EXPECT_EQ("20,20 40x40", w11->GetBoundsInScreen().ToString());
  523. EXPECT_EQ("50,30 80x80", w11_t1->GetBoundsInScreen().ToString());
  524. w1->SetBoundsInScreen(gfx::Rect(1200, 10, 100, 100), GetSecondaryDisplay());
  525. EXPECT_EQ(root_windows[1], w1->GetRootWindow());
  526. EXPECT_EQ(root_windows[1], w1_t1->GetRootWindow());
  527. EXPECT_EQ(root_windows[1], w1_t11->GetRootWindow());
  528. EXPECT_EQ(root_windows[1], w11->GetRootWindow());
  529. EXPECT_EQ(root_windows[1], w11_t1->GetRootWindow());
  530. EXPECT_EQ("1200,10 100x100", w1->GetBoundsInScreen().ToString());
  531. EXPECT_EQ("1250,60 50x50", w1_t1->GetBoundsInScreen().ToString());
  532. EXPECT_EQ("1252,67 35x35", w1_t11->GetBoundsInScreen().ToString());
  533. EXPECT_EQ("1210,20 40x40", w11->GetBoundsInScreen().ToString());
  534. EXPECT_EQ("1240,30 80x80", w11_t1->GetBoundsInScreen().ToString());
  535. }
  536. // Test transient child is parented after its transient parent moved to another
  537. // root window.
  538. TEST_F(ExtendedDesktopTest, PostMoveParentTransientChild) {
  539. UpdateDisplay("600x400,600x400");
  540. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  541. // Create and activate a normal window.
  542. aura::Window* window =
  543. CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 100, 100));
  544. wm::ActivateWindow(window);
  545. // Create a transient child window of |window| without parenting to |window|
  546. // yet.
  547. std::unique_ptr<aura::Window> child = std::make_unique<aura::Window>(nullptr);
  548. child->SetType(aura::client::WINDOW_TYPE_NORMAL);
  549. child->Init(ui::LAYER_TEXTURED);
  550. child->SetBounds(gfx::Rect(50, 50, 50, 50));
  551. child->Show();
  552. ::wm::AddTransientChild(window, child.get());
  553. // Move |window| to another display and ensure that crash doesn't happen.
  554. window->SetBoundsInScreen(gfx::Rect(610, 10, 100, 100),
  555. GetSecondaryDisplay());
  556. // Parent |child| to |window| now.
  557. window->AddChild(child.get());
  558. EXPECT_EQ(root_windows[1], window->GetRootWindow());
  559. EXPECT_EQ(root_windows[1], child->GetRootWindow());
  560. EXPECT_EQ("610,10 100x100", window->GetBoundsInScreen().ToString());
  561. EXPECT_EQ("660,60 50x50", child->GetBoundsInScreen().ToString());
  562. }
  563. // Test if the Window::ConvertPointToTarget works across root windows.
  564. TEST_F(ExtendedDesktopTest, ConvertPoint) {
  565. display::Screen* screen = display::Screen::GetScreen();
  566. UpdateDisplay("1000x600,600x400");
  567. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  568. display::Display display_1 = screen->GetDisplayNearestWindow(root_windows[0]);
  569. EXPECT_EQ("0,0", display_1.bounds().origin().ToString());
  570. display::Display display_2 = screen->GetDisplayNearestWindow(root_windows[1]);
  571. EXPECT_EQ("1000,0", display_2.bounds().origin().ToString());
  572. aura::Window* d1 =
  573. CreateTestWidget(gfx::Rect(10, 10, 100, 100))->GetNativeView();
  574. aura::Window* d2 =
  575. CreateTestWidget(gfx::Rect(1020, 20, 100, 100))->GetNativeView();
  576. EXPECT_EQ(root_windows[0], d1->GetRootWindow());
  577. EXPECT_EQ(root_windows[1], d2->GetRootWindow());
  578. // Convert point in the Root2's window to the Root1's window Coord.
  579. gfx::Point p(0, 0);
  580. aura::Window::ConvertPointToTarget(root_windows[1], root_windows[0], &p);
  581. EXPECT_EQ("1000,0", p.ToString());
  582. p.SetPoint(0, 0);
  583. aura::Window::ConvertPointToTarget(d2, d1, &p);
  584. EXPECT_EQ("1010,10", p.ToString());
  585. // Convert point in the Root1's window to the Root2's window Coord.
  586. p.SetPoint(0, 0);
  587. aura::Window::ConvertPointToTarget(root_windows[0], root_windows[1], &p);
  588. EXPECT_EQ("-1000,0", p.ToString());
  589. p.SetPoint(0, 0);
  590. aura::Window::ConvertPointToTarget(d1, d2, &p);
  591. EXPECT_EQ("-1010,-10", p.ToString());
  592. // Move the 2nd display to the bottom and test again.
  593. SetSecondaryDisplayLayout(display::DisplayPlacement::BOTTOM);
  594. display_2 = screen->GetDisplayNearestWindow(root_windows[1]);
  595. EXPECT_EQ("0,600", display_2.bounds().origin().ToString());
  596. // Convert point in Root2's window to Root1's window Coord.
  597. p.SetPoint(0, 0);
  598. aura::Window::ConvertPointToTarget(root_windows[1], root_windows[0], &p);
  599. EXPECT_EQ("0,600", p.ToString());
  600. p.SetPoint(0, 0);
  601. aura::Window::ConvertPointToTarget(d2, d1, &p);
  602. EXPECT_EQ("10,610", p.ToString());
  603. // Convert point in Root1's window to Root2's window Coord.
  604. p.SetPoint(0, 0);
  605. aura::Window::ConvertPointToTarget(root_windows[0], root_windows[1], &p);
  606. EXPECT_EQ("0,-600", p.ToString());
  607. p.SetPoint(0, 0);
  608. aura::Window::ConvertPointToTarget(d1, d2, &p);
  609. EXPECT_EQ("-10,-610", p.ToString());
  610. }
  611. TEST_F(ExtendedDesktopTest, OpenSystemTray) {
  612. // Two displays side by side and both are high enough for tray bubble.
  613. UpdateDisplay("500x600,600x700");
  614. ASSERT_FALSE(IsBubbleShown());
  615. ui::test::EventGenerator* event_generator = GetEventGenerator();
  616. // Opens the tray by a dummy click event and makes sure that adding/removing
  617. // displays doesn't break anything.
  618. event_generator->MoveMouseTo(GetSystemTrayBoundsInScreen().CenterPoint());
  619. event_generator->ClickLeftButton();
  620. EXPECT_TRUE(IsBubbleShown());
  621. // Verifies that the bubble is within the primary display.
  622. const gfx::Rect primary_display_bounds = GetPrimaryDisplay().bounds();
  623. const gfx::Rect tray_bubble_bounds =
  624. GetPrimaryUnifiedSystemTray()->GetBubbleBoundsInScreen();
  625. EXPECT_TRUE(primary_display_bounds.Contains(tray_bubble_bounds))
  626. << "primary display bounds=" << primary_display_bounds.ToString()
  627. << ", tray bubble bounds=" << tray_bubble_bounds.ToString();
  628. UpdateDisplay("500x600");
  629. EXPECT_TRUE(IsBubbleShown());
  630. UpdateDisplay("500x600,600x700");
  631. EXPECT_TRUE(IsBubbleShown());
  632. // Closes the tray and again makes sure that adding/removing displays doesn't
  633. // break anything.
  634. event_generator->ClickLeftButton();
  635. base::RunLoop().RunUntilIdle();
  636. EXPECT_FALSE(IsBubbleShown());
  637. UpdateDisplay("500x600");
  638. EXPECT_FALSE(IsBubbleShown());
  639. UpdateDisplay("500x600,600x700");
  640. EXPECT_FALSE(IsBubbleShown());
  641. }
  642. TEST_F(ExtendedDesktopTest, StayInSameRootWindow) {
  643. UpdateDisplay("200x100,300x200");
  644. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  645. views::Widget* w1 = CreateTestWidget(gfx::Rect(10, 10, 50, 50));
  646. EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow());
  647. w1->SetBounds(gfx::Rect(250, 10, 50, 50));
  648. EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
  649. // The widget stays in the same root if kLockedToRootKey is set to true.
  650. w1->GetNativeView()->SetProperty(kLockedToRootKey, true);
  651. w1->SetBounds(gfx::Rect(10, 10, 50, 50));
  652. EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
  653. // The widget should now move to the 1st root window without the property.
  654. w1->GetNativeView()->ClearProperty(kLockedToRootKey);
  655. w1->SetBounds(gfx::Rect(10, 10, 50, 50));
  656. EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow());
  657. // a window in SettingsBubbleContainer, ShelfControlContainer and
  658. // OverviewFocusContainer should not move to another root window
  659. // regardless of the bounds specified.
  660. aura::Window* settings_bubble_container =
  661. Shell::GetPrimaryRootWindowController()->GetContainer(
  662. kShellWindowId_SettingBubbleContainer);
  663. aura::Window* window =
  664. aura::test::CreateTestWindowWithId(100, settings_bubble_container);
  665. window->SetBoundsInScreen(gfx::Rect(250, 10, 50, 50), GetSecondaryDisplay());
  666. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  667. aura::Window* status_container =
  668. Shell::GetPrimaryRootWindowController()->GetContainer(
  669. kShellWindowId_ShelfContainer);
  670. window = aura::test::CreateTestWindowWithId(100, status_container);
  671. window->SetBoundsInScreen(gfx::Rect(250, 10, 50, 50), GetSecondaryDisplay());
  672. EXPECT_EQ(root_windows[0], window->GetRootWindow());
  673. }
  674. TEST_F(ExtendedDesktopTest, KeyEventsOnLockScreen) {
  675. UpdateDisplay("200x100,300x200");
  676. aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  677. // Create normal windows on both displays.
  678. views::Widget* widget1 = CreateTestWidget(
  679. display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  680. widget1->Show();
  681. EXPECT_EQ(root_windows[0], widget1->GetNativeView()->GetRootWindow());
  682. views::Widget* widget2 = CreateTestWidget(GetSecondaryDisplay().bounds());
  683. widget2->Show();
  684. EXPECT_EQ(root_windows[1], widget2->GetNativeView()->GetRootWindow());
  685. // Create a LockScreen window.
  686. views::Widget* lock_widget = CreateTestWidget(
  687. display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  688. views::Textfield* textfield = new views::Textfield;
  689. lock_widget->client_view()->AddChildView(textfield);
  690. Shell::GetContainer(Shell::GetPrimaryRootWindow(),
  691. kShellWindowId_LockScreenContainer)
  692. ->AddChild(lock_widget->GetNativeView());
  693. lock_widget->Show();
  694. textfield->RequestFocus();
  695. aura::client::FocusClient* focus_client =
  696. aura::client::GetFocusClient(root_windows[0]);
  697. EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
  698. // The lock window should get events on both root windows.
  699. ui::test::EventGenerator* event_generator = GetEventGenerator();
  700. event_generator->set_current_target(root_windows[0]);
  701. event_generator->PressAndReleaseKey(ui::VKEY_A);
  702. EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
  703. EXPECT_EQ("a", base::UTF16ToASCII(textfield->GetText()));
  704. event_generator->set_current_target(root_windows[1]);
  705. event_generator->PressAndReleaseKey(ui::VKEY_B);
  706. EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
  707. EXPECT_EQ("ab", base::UTF16ToASCII(textfield->GetText()));
  708. // Deleting 2nd display. The lock window still should get the events.
  709. UpdateDisplay("200x100");
  710. event_generator->set_current_target(root_windows[0]);
  711. event_generator->PressAndReleaseKey(ui::VKEY_C);
  712. EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
  713. EXPECT_EQ("abc", base::UTF16ToASCII(textfield->GetText()));
  714. // Creating 2nd display again, and lock window still should get events
  715. // on both root windows.
  716. UpdateDisplay("200x100,300x200");
  717. root_windows = Shell::GetAllRootWindows();
  718. event_generator->set_current_target(root_windows[0]);
  719. event_generator->PressAndReleaseKey(ui::VKEY_D);
  720. EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
  721. EXPECT_EQ("abcd", base::UTF16ToASCII(textfield->GetText()));
  722. event_generator->set_current_target(root_windows[1]);
  723. event_generator->PressAndReleaseKey(ui::VKEY_E);
  724. EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
  725. EXPECT_EQ("abcde", base::UTF16ToASCII(textfield->GetText()));
  726. }
  727. // Verifies that clicking in the primary display and dragging to the secondary
  728. // display correctly sets the event location (window local) and root_location
  729. // (in screen coordinates) for the mouse event. https://crrev.com/11691010
  730. TEST_F(ExtendedDesktopTest, PassiveGrab) {
  731. // This test deals with input events but not visuals so don't throttle input
  732. // on visuals.
  733. aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false);
  734. EventLocationRecordingEventHandler event_handler;
  735. Shell::Get()->AddPreTargetHandler(&event_handler);
  736. // Create large displays so the widget won't be moved after creation.
  737. // https://crbug.com/890633
  738. UpdateDisplay("1000x900,1000x900");
  739. views::Widget* widget = CreateTestWidget(gfx::Rect(50, 50, 200, 200));
  740. widget->Show();
  741. ASSERT_EQ("50,50 200x200", widget->GetWindowBoundsInScreen().ToString());
  742. // Move the mouse to the center of the window.
  743. ui::test::EventGenerator* generator = GetEventGenerator();
  744. generator->MoveMouseTo(150, 150);
  745. // Location is relative to the window.
  746. EXPECT_EQ("100,100", event_handler.GetLocation());
  747. // Root location is relative to the display.
  748. EXPECT_EQ("150,150", event_handler.GetRootLocation());
  749. event_handler.Reset();
  750. // Drag the mouse to the secondary display. Does not drag the window.
  751. generator->PressLeftButton();
  752. generator->MoveMouseBy(1000, 0);
  753. // Location is relative to the original window.
  754. EXPECT_EQ("1100,100", event_handler.GetLocation());
  755. // Root location is relative to the original display.
  756. EXPECT_EQ("1150,150", event_handler.GetRootLocation());
  757. event_handler.Reset();
  758. // End the drag.
  759. generator->ReleaseLeftButton();
  760. EXPECT_EQ("-999,-999", event_handler.GetRootLocation());
  761. EXPECT_EQ("-999,-999", event_handler.GetLocation());
  762. event_handler.Reset();
  763. // Move the mouse to the top-left of the secondary display.
  764. generator->MoveMouseTo(1001, 1);
  765. // Location is relative to the new display.
  766. EXPECT_EQ("1,1", event_handler.GetLocation());
  767. // Root location is relative to the new display.
  768. EXPECT_EQ("1,1", event_handler.GetRootLocation());
  769. event_handler.Reset();
  770. Shell::Get()->RemovePreTargetHandler(&event_handler);
  771. }
  772. } // namespace ash