window_manager_unittest.cc 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  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/shell.h"
  6. #include "ash/test/ash_test_base.h"
  7. #include "ash/test/test_window_builder.h"
  8. #include "ash/wm/test_activation_delegate.h"
  9. #include "ash/wm/window_util.h"
  10. #include "ui/aura/client/aura_constants.h"
  11. #include "ui/aura/client/cursor_client_observer.h"
  12. #include "ui/aura/client/focus_client.h"
  13. #include "ui/aura/env.h"
  14. #include "ui/aura/test/aura_test_base.h"
  15. #include "ui/aura/test/test_window_delegate.h"
  16. #include "ui/aura/test/test_windows.h"
  17. #include "ui/base/cursor/cursor.h"
  18. #include "ui/base/cursor/cursor_size.h"
  19. #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
  20. #include "ui/base/hit_test.h"
  21. #include "ui/display/screen.h"
  22. #include "ui/events/event.h"
  23. #include "ui/events/event_sink.h"
  24. #include "ui/events/event_utils.h"
  25. #include "ui/events/test/event_generator.h"
  26. #include "ui/events/test/test_event_handler.h"
  27. #include "ui/wm/core/compound_event_filter.h"
  28. #include "ui/wm/public/activation_client.h"
  29. #include "ui/wm/public/activation_delegate.h"
  30. #include "ui/wm/test/testing_cursor_client_observer.h"
  31. namespace {
  32. base::TimeTicks getTime() {
  33. return ui::EventTimeForNow();
  34. }
  35. // A slightly changed TestEventHandler which can be configured to return a
  36. // specified value for key/mouse event handling.
  37. class CustomEventHandler : public ui::test::TestEventHandler {
  38. public:
  39. CustomEventHandler()
  40. : key_result_(ui::ER_UNHANDLED), mouse_result_(ui::ER_UNHANDLED) {}
  41. CustomEventHandler(const CustomEventHandler&) = delete;
  42. CustomEventHandler& operator=(const CustomEventHandler&) = delete;
  43. ~CustomEventHandler() override = default;
  44. void set_key_event_handling_result(ui::EventResult result) {
  45. key_result_ = result;
  46. }
  47. void set_mouse_event_handling_result(ui::EventResult result) {
  48. mouse_result_ = result;
  49. }
  50. // Overridden from ui::EventHandler:
  51. void OnKeyEvent(ui::KeyEvent* event) override {
  52. ui::test::TestEventHandler::OnKeyEvent(event);
  53. if (key_result_ & ui::ER_HANDLED)
  54. event->SetHandled();
  55. if (key_result_ & ui::ER_CONSUMED)
  56. event->StopPropagation();
  57. }
  58. void OnMouseEvent(ui::MouseEvent* event) override {
  59. ui::test::TestEventHandler::OnMouseEvent(event);
  60. if (mouse_result_ & ui::ER_HANDLED)
  61. event->SetHandled();
  62. if (mouse_result_ & ui::ER_CONSUMED)
  63. event->StopPropagation();
  64. }
  65. private:
  66. ui::EventResult key_result_;
  67. ui::EventResult mouse_result_;
  68. };
  69. } // namespace
  70. namespace ash {
  71. class WindowManagerTest : public AshTestBase {
  72. public:
  73. WindowManagerTest() = default;
  74. WindowManagerTest(const WindowManagerTest&) = delete;
  75. WindowManagerTest& operator=(const WindowManagerTest&) = delete;
  76. ~WindowManagerTest() override = default;
  77. void SetUp() override {
  78. AshTestBase::SetUp();
  79. // Shell hides the cursor by default; show it for these tests.
  80. Shell::Get()->cursor_manager()->ShowCursor();
  81. }
  82. };
  83. class NonFocusableDelegate : public aura::test::TestWindowDelegate {
  84. public:
  85. NonFocusableDelegate() = default;
  86. NonFocusableDelegate(const NonFocusableDelegate&) = delete;
  87. NonFocusableDelegate& operator=(const NonFocusableDelegate&) = delete;
  88. private:
  89. bool CanFocus() override { return false; }
  90. };
  91. class HitTestWindowDelegate : public aura::test::TestWindowDelegate {
  92. public:
  93. HitTestWindowDelegate() : hittest_code_(HTNOWHERE) {}
  94. HitTestWindowDelegate(const HitTestWindowDelegate&) = delete;
  95. HitTestWindowDelegate& operator=(const HitTestWindowDelegate&) = delete;
  96. ~HitTestWindowDelegate() override = default;
  97. void set_hittest_code(int hittest_code) { hittest_code_ = hittest_code; }
  98. private:
  99. // Overridden from TestWindowDelegate:
  100. int GetNonClientComponent(const gfx::Point& point) const override {
  101. return hittest_code_;
  102. }
  103. int hittest_code_;
  104. };
  105. TEST_F(WindowManagerTest, Focus) {
  106. // The IME event filter interferes with the basic key event propagation we
  107. // attempt to do here, so we disable it.
  108. //
  109. DisableIME();
  110. aura::Window* root_window = Shell::GetPrimaryRootWindow();
  111. root_window->SetBounds(gfx::Rect(0, 0, 510, 510));
  112. // Supplied ids are negative so as not to collide with shell ids.
  113. // TODO(beng): maybe introduce a MAKE_SHELL_ID() macro that generates a safe
  114. // id beyond shell id max?
  115. std::unique_ptr<aura::Window> w1 = TestWindowBuilder()
  116. .SetColorWindowDelegate(SK_ColorWHITE)
  117. .SetBounds(gfx::Rect(10, 10, 500, 500))
  118. .Build();
  119. std::unique_ptr<aura::Window> w11(aura::test::CreateTestWindow(
  120. SK_ColorGREEN, -11, gfx::Rect(5, 5, 100, 100), w1.get()));
  121. std::unique_ptr<aura::Window> w111(aura::test::CreateTestWindow(
  122. SK_ColorCYAN, -111, gfx::Rect(5, 5, 75, 75), w11.get()));
  123. std::unique_ptr<aura::Window> w1111(aura::test::CreateTestWindow(
  124. SK_ColorRED, -1111, gfx::Rect(5, 5, 50, 50), w111.get()));
  125. std::unique_ptr<aura::Window> w12(aura::test::CreateTestWindow(
  126. SK_ColorMAGENTA, -12, gfx::Rect(10, 420, 25, 25), w1.get()));
  127. aura::test::ColorTestWindowDelegate* w121delegate =
  128. new aura::test::ColorTestWindowDelegate(SK_ColorYELLOW);
  129. std::unique_ptr<aura::Window> w121(aura::test::CreateTestWindowWithDelegate(
  130. w121delegate, -121, gfx::Rect(5, 5, 5, 5), w12.get()));
  131. aura::test::ColorTestWindowDelegate* w122delegate =
  132. new aura::test::ColorTestWindowDelegate(SK_ColorRED);
  133. std::unique_ptr<aura::Window> w122(aura::test::CreateTestWindowWithDelegate(
  134. w122delegate, -122, gfx::Rect(10, 5, 5, 5), w12.get()));
  135. aura::test::ColorTestWindowDelegate* w123delegate =
  136. new aura::test::ColorTestWindowDelegate(SK_ColorRED);
  137. std::unique_ptr<aura::Window> w123(aura::test::CreateTestWindowWithDelegate(
  138. w123delegate, -123, gfx::Rect(15, 5, 5, 5), w12.get()));
  139. std::unique_ptr<aura::Window> w13(aura::test::CreateTestWindow(
  140. SK_ColorGRAY, -13, gfx::Rect(5, 470, 50, 50), w1.get()));
  141. // Click on a sub-window (w121) to focus it.
  142. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w121.get());
  143. generator.ClickLeftButton();
  144. aura::client::FocusClient* focus_client =
  145. aura::client::GetFocusClient(w121.get());
  146. EXPECT_EQ(w121.get(), focus_client->GetFocusedWindow());
  147. ui::EventSink* sink = root_window->GetHost()->GetEventSink();
  148. // The key press should be sent to the focused sub-window.
  149. ui::KeyEvent keyev(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  150. ui::EventDispatchDetails details = sink->OnEventFromSource(&keyev);
  151. ASSERT_FALSE(details.dispatcher_destroyed);
  152. EXPECT_EQ(ui::VKEY_E, w121delegate->last_key_code());
  153. // Touch on a sub-window (w122) to focus it.
  154. gfx::Point click_point = w122->bounds().CenterPoint();
  155. aura::Window::ConvertPointToTarget(w122->parent(), root_window, &click_point);
  156. ui::TouchEvent touchev(ui::ET_TOUCH_PRESSED, click_point, getTime(),
  157. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  158. details = sink->OnEventFromSource(&touchev);
  159. ASSERT_FALSE(details.dispatcher_destroyed);
  160. focus_client = aura::client::GetFocusClient(w122.get());
  161. EXPECT_EQ(w122.get(), focus_client->GetFocusedWindow());
  162. // The key press should be sent to the focused sub-window.
  163. keyev = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  164. details = sink->OnEventFromSource(&keyev);
  165. ASSERT_FALSE(details.dispatcher_destroyed);
  166. EXPECT_EQ(ui::VKEY_E, w122delegate->last_key_code());
  167. // Hiding the focused window will set the focus to its parent if
  168. // it's focusable.
  169. w122->Hide();
  170. EXPECT_EQ(aura::client::GetFocusClient(w12.get()),
  171. aura::client::GetFocusClient(w122.get()));
  172. EXPECT_EQ(w12.get(),
  173. aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  174. // Sets the focus back to w122.
  175. w122->Show();
  176. w122->Focus();
  177. EXPECT_EQ(w122.get(),
  178. aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  179. // Removing the focused window from parent should set the focus to
  180. // its parent if it's focusable.
  181. w12->RemoveChild(w122.get());
  182. EXPECT_EQ(NULL, aura::client::GetFocusClient(w122.get()));
  183. EXPECT_EQ(w12.get(),
  184. aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  185. // Set the focus to w123, but make the w1 not activatable.
  186. TestActivationDelegate activation_delegate(false);
  187. w123->Focus();
  188. EXPECT_EQ(w123.get(),
  189. aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  190. ::wm::SetActivationDelegate(w1.get(), &activation_delegate);
  191. // Hiding the focused window will set the focus to NULL because
  192. // parent window is not focusable.
  193. w123->Hide();
  194. EXPECT_EQ(aura::client::GetFocusClient(w12.get()),
  195. aura::client::GetFocusClient(w123.get()));
  196. EXPECT_EQ(NULL, aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  197. keyev = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  198. details = sink->OnEventFromSource(&keyev);
  199. EXPECT_FALSE(keyev.handled() || details.dispatcher_destroyed);
  200. // Set the focus back to w123
  201. ::wm::SetActivationDelegate(w1.get(), NULL);
  202. w123->Show();
  203. w123->Focus();
  204. EXPECT_EQ(w123.get(),
  205. aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  206. ::wm::SetActivationDelegate(w1.get(), &activation_delegate);
  207. // Removing the focused window will set the focus to NULL because
  208. // parent window is not focusable.
  209. w12->RemoveChild(w123.get());
  210. EXPECT_EQ(NULL, aura::client::GetFocusClient(w123.get()));
  211. keyev = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  212. details = sink->OnEventFromSource(&keyev);
  213. EXPECT_FALSE(keyev.handled() || details.dispatcher_destroyed);
  214. // Must set to NULL since the activation delegate will be destroyed before
  215. // the windows.
  216. ::wm::SetActivationDelegate(w1.get(), NULL);
  217. }
  218. // Various assertion testing for activating windows.
  219. TEST_F(WindowManagerTest, ActivateOnMouse) {
  220. aura::Window* root_window = Shell::GetPrimaryRootWindow();
  221. TestActivationDelegate d1;
  222. aura::test::TestWindowDelegate wd;
  223. std::unique_ptr<aura::Window> w1(
  224. CreateTestWindowInShellWithDelegate(&wd, -1, gfx::Rect(10, 10, 50, 50)));
  225. d1.SetWindow(w1.get());
  226. TestActivationDelegate d2;
  227. std::unique_ptr<aura::Window> w2(
  228. CreateTestWindowInShellWithDelegate(&wd, -2, gfx::Rect(70, 70, 50, 50)));
  229. d2.SetWindow(w2.get());
  230. aura::client::FocusClient* focus_client =
  231. aura::client::GetFocusClient(w1.get());
  232. d1.Clear();
  233. d2.Clear();
  234. // Activate window1.
  235. wm::ActivateWindow(w1.get());
  236. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  237. EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  238. EXPECT_EQ(1, d1.activated_count());
  239. EXPECT_EQ(0, d1.lost_active_count());
  240. d1.Clear();
  241. {
  242. // Click on window2.
  243. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w2.get());
  244. generator.ClickLeftButton();
  245. // Window2 should have become active.
  246. EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  247. EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  248. EXPECT_EQ(0, d1.activated_count());
  249. EXPECT_EQ(1, d1.lost_active_count());
  250. EXPECT_EQ(1, d2.activated_count());
  251. EXPECT_EQ(0, d2.lost_active_count());
  252. d1.Clear();
  253. d2.Clear();
  254. }
  255. {
  256. // Click back on window1, but set it up so w1 doesn't activate on click.
  257. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w1.get());
  258. d1.set_activate(false);
  259. generator.ClickLeftButton();
  260. // Window2 should still be active and focused.
  261. EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  262. EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  263. EXPECT_EQ(0, d1.activated_count());
  264. EXPECT_EQ(0, d1.lost_active_count());
  265. EXPECT_EQ(0, d2.activated_count());
  266. EXPECT_EQ(0, d2.lost_active_count());
  267. d1.Clear();
  268. d2.Clear();
  269. }
  270. // Destroy window2, this should make window1 active.
  271. d1.set_activate(true);
  272. w2.reset();
  273. EXPECT_EQ(0, d2.activated_count());
  274. EXPECT_EQ(1, d2.lost_active_count());
  275. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  276. EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  277. EXPECT_EQ(1, d1.activated_count());
  278. EXPECT_EQ(0, d1.lost_active_count());
  279. // Clicking an active window with a child shouldn't steal the
  280. // focus from the child.
  281. {
  282. std::unique_ptr<aura::Window> w11(CreateTestWindowWithDelegate(
  283. &wd, -11, gfx::Rect(10, 10, 10, 10), w1.get()));
  284. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
  285. w11.get());
  286. // First set the focus to the child |w11|.
  287. generator.ClickLeftButton();
  288. EXPECT_EQ(w11.get(), focus_client->GetFocusedWindow());
  289. EXPECT_EQ(w1.get(), window_util::GetActiveWindow());
  290. // Then click the parent active window. The focus shouldn't move.
  291. gfx::Point left_top = w1->bounds().origin();
  292. aura::Window::ConvertPointToTarget(w1->parent(), root_window, &left_top);
  293. left_top.Offset(1, 1);
  294. generator.MoveMouseTo(left_top);
  295. generator.ClickLeftButton();
  296. EXPECT_EQ(w11.get(), focus_client->GetFocusedWindow());
  297. EXPECT_EQ(w1.get(), window_util::GetActiveWindow());
  298. }
  299. // Clicking on a non-focusable window inside a background window should still
  300. // give focus to the background window.
  301. {
  302. NonFocusableDelegate nfd;
  303. std::unique_ptr<aura::Window> w11(CreateTestWindowWithDelegate(
  304. &nfd, -1, gfx::Rect(10, 10, 10, 10), w1.get()));
  305. // Move focus to |w2| first.
  306. std::unique_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
  307. &wd, -1, gfx::Rect(70, 70, 50, 50)));
  308. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w2.get());
  309. generator.ClickLeftButton();
  310. EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  311. EXPECT_FALSE(w11->CanFocus());
  312. // Click on |w11|. This should focus w1.
  313. generator.MoveMouseToCenterOf(w11.get());
  314. generator.ClickLeftButton();
  315. EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  316. }
  317. }
  318. // Tests that Set window property |kActivateOnPointerKey| to false could
  319. // properly ignore pointer window activation.
  320. TEST_F(WindowManagerTest, ActivateOnPointerWindowProperty) {
  321. // Create two test windows, window1 and window2.
  322. aura::test::TestWindowDelegate wd;
  323. std::unique_ptr<aura::Window> w1(
  324. CreateTestWindowInShellWithDelegate(&wd, -1, gfx::Rect(10, 10, 50, 50)));
  325. std::unique_ptr<aura::Window> w2(
  326. CreateTestWindowInShellWithDelegate(&wd, -2, gfx::Rect(70, 70, 50, 50)));
  327. // Activate window1.
  328. wm::ActivateWindow(w1.get());
  329. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  330. EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
  331. // Set window2 not pointer activatable.
  332. w2->SetProperty(aura::client::kActivateOnPointerKey, false);
  333. // Mouse click on window2.
  334. ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w2.get());
  335. generator.ClickLeftButton();
  336. // Window2 should not become active.
  337. EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
  338. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  339. // Gesture a tap at window2.
  340. generator.GestureTapAt(w2->bounds().CenterPoint());
  341. // Window2 should not become active.
  342. EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
  343. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  344. // Set window2 now pointer activatable.
  345. w2->SetProperty(aura::client::kActivateOnPointerKey, true);
  346. // Mouse click on window2.
  347. generator.ClickLeftButton();
  348. // Window2 should become active.
  349. EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  350. EXPECT_FALSE(wm::IsActiveWindow(w1.get()));
  351. }
  352. // Essentially the same as ActivateOnMouse, but for touch events.
  353. TEST_F(WindowManagerTest, ActivateOnTouch) {
  354. aura::Window* root_window = Shell::GetPrimaryRootWindow();
  355. TestActivationDelegate d1;
  356. aura::test::TestWindowDelegate wd;
  357. std::unique_ptr<aura::Window> w1(
  358. CreateTestWindowInShellWithDelegate(&wd, -1, gfx::Rect(10, 10, 50, 50)));
  359. d1.SetWindow(w1.get());
  360. TestActivationDelegate d2;
  361. std::unique_ptr<aura::Window> w2(
  362. CreateTestWindowInShellWithDelegate(&wd, -2, gfx::Rect(70, 70, 50, 50)));
  363. d2.SetWindow(w2.get());
  364. aura::client::FocusClient* focus_client =
  365. aura::client::GetFocusClient(w1.get());
  366. d1.Clear();
  367. d2.Clear();
  368. // Activate window1.
  369. wm::ActivateWindow(w1.get());
  370. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  371. EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  372. EXPECT_EQ(1, d1.activated_count());
  373. EXPECT_EQ(0, d1.lost_active_count());
  374. d1.Clear();
  375. // Touch window2.
  376. gfx::Point press_point = w2->bounds().CenterPoint();
  377. aura::Window::ConvertPointToTarget(w2->parent(), root_window, &press_point);
  378. ui::TouchEvent touchev1(ui::ET_TOUCH_PRESSED, press_point, getTime(),
  379. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  380. ui::EventSink* sink = root_window->GetHost()->GetEventSink();
  381. ui::EventDispatchDetails details = sink->OnEventFromSource(&touchev1);
  382. ASSERT_FALSE(details.dispatcher_destroyed);
  383. // Window2 should have become active.
  384. EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  385. EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  386. EXPECT_EQ(0, d1.activated_count());
  387. EXPECT_EQ(1, d1.lost_active_count());
  388. EXPECT_EQ(1, d2.activated_count());
  389. EXPECT_EQ(0, d2.lost_active_count());
  390. d1.Clear();
  391. d2.Clear();
  392. // Touch window1, but set it up so w1 doesn't activate on touch.
  393. press_point = w1->bounds().CenterPoint();
  394. aura::Window::ConvertPointToTarget(w1->parent(), root_window, &press_point);
  395. d1.set_activate(false);
  396. ui::TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, getTime(),
  397. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  398. details = sink->OnEventFromSource(&touchev2);
  399. ASSERT_FALSE(details.dispatcher_destroyed);
  400. // Window2 should still be active and focused.
  401. EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  402. EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  403. EXPECT_EQ(0, d1.activated_count());
  404. EXPECT_EQ(0, d1.lost_active_count());
  405. EXPECT_EQ(0, d2.activated_count());
  406. EXPECT_EQ(0, d2.lost_active_count());
  407. d1.Clear();
  408. d2.Clear();
  409. // Destroy window2, this should make window1 active.
  410. d1.set_activate(true);
  411. w2.reset();
  412. EXPECT_EQ(0, d2.activated_count());
  413. EXPECT_EQ(1, d2.lost_active_count());
  414. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  415. EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  416. EXPECT_EQ(1, d1.activated_count());
  417. EXPECT_EQ(0, d1.lost_active_count());
  418. }
  419. TEST_F(WindowManagerTest, MouseEventCursors) {
  420. aura::Window* root_window = Shell::GetPrimaryRootWindow();
  421. // Create a window.
  422. const int kWindowLeft = 123;
  423. const int kWindowTop = 45;
  424. HitTestWindowDelegate window_delegate;
  425. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
  426. &window_delegate, -1, gfx::Rect(kWindowLeft, kWindowTop, 640, 480)));
  427. // Create two mouse movement events we can switch between.
  428. gfx::Point point1(kWindowLeft, kWindowTop);
  429. aura::Window::ConvertPointToTarget(window->parent(), root_window, &point1);
  430. gfx::Point point2(kWindowLeft + 1, kWindowTop + 1);
  431. aura::Window::ConvertPointToTarget(window->parent(), root_window, &point2);
  432. aura::WindowTreeHost* host = root_window->GetHost();
  433. ui::EventSink* sink = host->GetEventSink();
  434. // Cursor starts as a pointer (set during Shell::Init()).
  435. EXPECT_EQ(ui::mojom::CursorType::kPointer, host->last_cursor().type());
  436. {
  437. // Resize edges and corners show proper cursors.
  438. window_delegate.set_hittest_code(HTBOTTOM);
  439. ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1,
  440. ui::EventTimeForNow(), 0, 0);
  441. ui::EventDispatchDetails details = sink->OnEventFromSource(&move1);
  442. ASSERT_FALSE(details.dispatcher_destroyed);
  443. EXPECT_EQ(ui::mojom::CursorType::kSouthResize, host->last_cursor().type());
  444. }
  445. {
  446. window_delegate.set_hittest_code(HTBOTTOMLEFT);
  447. ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2,
  448. ui::EventTimeForNow(), 0, 0);
  449. ui::EventDispatchDetails details = sink->OnEventFromSource(&move2);
  450. ASSERT_FALSE(details.dispatcher_destroyed);
  451. EXPECT_EQ(ui::mojom::CursorType::kSouthWestResize,
  452. host->last_cursor().type());
  453. }
  454. {
  455. window_delegate.set_hittest_code(HTBOTTOMRIGHT);
  456. ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1,
  457. ui::EventTimeForNow(), 0, 0);
  458. ui::EventDispatchDetails details = sink->OnEventFromSource(&move1);
  459. ASSERT_FALSE(details.dispatcher_destroyed);
  460. EXPECT_EQ(ui::mojom::CursorType::kSouthEastResize,
  461. host->last_cursor().type());
  462. }
  463. {
  464. window_delegate.set_hittest_code(HTLEFT);
  465. ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2,
  466. ui::EventTimeForNow(), 0, 0);
  467. ui::EventDispatchDetails details = sink->OnEventFromSource(&move2);
  468. ASSERT_FALSE(details.dispatcher_destroyed);
  469. EXPECT_EQ(ui::mojom::CursorType::kWestResize, host->last_cursor().type());
  470. }
  471. {
  472. window_delegate.set_hittest_code(HTRIGHT);
  473. ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1,
  474. ui::EventTimeForNow(), 0, 0);
  475. ui::EventDispatchDetails details = sink->OnEventFromSource(&move1);
  476. ASSERT_FALSE(details.dispatcher_destroyed);
  477. EXPECT_EQ(ui::mojom::CursorType::kEastResize, host->last_cursor().type());
  478. }
  479. {
  480. window_delegate.set_hittest_code(HTTOP);
  481. ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2,
  482. ui::EventTimeForNow(), 0, 0);
  483. ui::EventDispatchDetails details = sink->OnEventFromSource(&move2);
  484. ASSERT_FALSE(details.dispatcher_destroyed);
  485. EXPECT_EQ(ui::mojom::CursorType::kNorthResize, host->last_cursor().type());
  486. }
  487. {
  488. window_delegate.set_hittest_code(HTTOPLEFT);
  489. ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1,
  490. ui::EventTimeForNow(), 0, 0);
  491. ui::EventDispatchDetails details = sink->OnEventFromSource(&move1);
  492. ASSERT_FALSE(details.dispatcher_destroyed);
  493. EXPECT_EQ(ui::mojom::CursorType::kNorthWestResize,
  494. host->last_cursor().type());
  495. }
  496. {
  497. window_delegate.set_hittest_code(HTTOPRIGHT);
  498. ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2,
  499. ui::EventTimeForNow(), 0, 0);
  500. ui::EventDispatchDetails details = sink->OnEventFromSource(&move2);
  501. ASSERT_FALSE(details.dispatcher_destroyed);
  502. EXPECT_EQ(ui::mojom::CursorType::kNorthEastResize,
  503. host->last_cursor().type());
  504. }
  505. {
  506. // Client area uses null cursor.
  507. window_delegate.set_hittest_code(HTCLIENT);
  508. ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1,
  509. ui::EventTimeForNow(), 0, 0);
  510. ui::EventDispatchDetails details = sink->OnEventFromSource(&move1);
  511. ASSERT_FALSE(details.dispatcher_destroyed);
  512. EXPECT_EQ(ui::mojom::CursorType::kNull, host->last_cursor().type());
  513. }
  514. }
  515. TEST_F(WindowManagerTest, TransformActivate) {
  516. aura::Window* root_window = Shell::GetPrimaryRootWindow();
  517. gfx::Size size = root_window->bounds().size();
  518. EXPECT_EQ(gfx::Rect(size).ToString(),
  519. display::Screen::GetScreen()
  520. ->GetDisplayNearestPoint(gfx::Point())
  521. .bounds()
  522. .ToString());
  523. // Rotate it clock-wise 90 degrees.
  524. gfx::Transform transform;
  525. transform.Translate(size.width(), 0);
  526. transform.Rotate(90.0f);
  527. root_window->GetHost()->SetRootTransform(transform);
  528. TestActivationDelegate d1;
  529. aura::test::TestWindowDelegate wd;
  530. std::unique_ptr<aura::Window> w1(
  531. CreateTestWindowInShellWithDelegate(&wd, 1, gfx::Rect(0, 15, 50, 50)));
  532. d1.SetWindow(w1.get());
  533. w1->Show();
  534. gfx::Point miss_point(5, 5);
  535. transform.TransformPoint(&miss_point);
  536. ui::MouseEvent mouseev1(ui::ET_MOUSE_PRESSED, miss_point, miss_point,
  537. ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
  538. ui::EF_LEFT_MOUSE_BUTTON);
  539. ui::EventSink* sink = root_window->GetHost()->GetEventSink();
  540. ui::EventDispatchDetails details = sink->OnEventFromSource(&mouseev1);
  541. ASSERT_FALSE(details.dispatcher_destroyed);
  542. EXPECT_EQ(NULL, aura::client::GetFocusClient(w1.get())->GetFocusedWindow());
  543. ui::MouseEvent mouseup(ui::ET_MOUSE_RELEASED, miss_point, miss_point,
  544. ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
  545. ui::EF_LEFT_MOUSE_BUTTON);
  546. details = sink->OnEventFromSource(&mouseup);
  547. ASSERT_FALSE(details.dispatcher_destroyed);
  548. gfx::Point hit_point(5, 15);
  549. transform.TransformPoint(&hit_point);
  550. ui::MouseEvent mouseev2(ui::ET_MOUSE_PRESSED, hit_point, hit_point,
  551. ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
  552. ui::EF_LEFT_MOUSE_BUTTON);
  553. details = sink->OnEventFromSource(&mouseev2);
  554. ASSERT_FALSE(details.dispatcher_destroyed);
  555. EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  556. EXPECT_EQ(w1.get(),
  557. aura::client::GetFocusClient(w1.get())->GetFocusedWindow());
  558. }
  559. TEST_F(WindowManagerTest, AdditionalFilters) {
  560. // The IME event filter interferes with the basic key event propagation we
  561. // attempt to do here, so we disable it.
  562. DisableIME();
  563. aura::Window* root_window = Shell::GetPrimaryRootWindow();
  564. // Creates a window and make it active
  565. std::unique_ptr<aura::Window> w1 =
  566. TestWindowBuilder().SetBounds(gfx::Rect(0, 0, 100, 100)).Build();
  567. wm::ActivateWindow(w1.get());
  568. // Creates two addition filters
  569. std::unique_ptr<CustomEventHandler> f1(new CustomEventHandler);
  570. std::unique_ptr<CustomEventHandler> f2(new CustomEventHandler);
  571. // Adds them to root window event filter.
  572. ::wm::CompoundEventFilter* env_filter = Shell::Get()->env_filter();
  573. env_filter->AddHandler(f1.get());
  574. env_filter->AddHandler(f2.get());
  575. // Dispatches mouse and keyboard events.
  576. ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
  577. ui::EventSink* sink = root_window->GetHost()->GetEventSink();
  578. ui::EventDispatchDetails details = sink->OnEventFromSource(&key_event);
  579. ASSERT_FALSE(details.dispatcher_destroyed);
  580. ui::MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0),
  581. gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0);
  582. details = sink->OnEventFromSource(&mouse_pressed);
  583. ASSERT_FALSE(details.dispatcher_destroyed);
  584. // Both filters should get the events.
  585. EXPECT_EQ(1, f1->num_key_events());
  586. EXPECT_EQ(1, f1->num_mouse_events());
  587. EXPECT_EQ(1, f2->num_key_events());
  588. EXPECT_EQ(1, f2->num_mouse_events());
  589. f1->Reset();
  590. f2->Reset();
  591. // Makes f1 consume events.
  592. f1->set_key_event_handling_result(ui::ER_CONSUMED);
  593. f1->set_mouse_event_handling_result(ui::ER_CONSUMED);
  594. // Dispatches events.
  595. details = sink->OnEventFromSource(&key_event);
  596. ASSERT_FALSE(details.dispatcher_destroyed);
  597. ui::MouseEvent mouse_released(ui::ET_MOUSE_RELEASED, gfx::Point(0, 0),
  598. gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0);
  599. details = sink->OnEventFromSource(&mouse_released);
  600. ASSERT_FALSE(details.dispatcher_destroyed);
  601. // f1 should still get the events but f2 no longer gets them.
  602. EXPECT_EQ(1, f1->num_key_events());
  603. EXPECT_EQ(1, f1->num_mouse_events());
  604. EXPECT_EQ(0, f2->num_key_events());
  605. EXPECT_EQ(0, f2->num_mouse_events());
  606. f1->Reset();
  607. f2->Reset();
  608. // Remove f1 from additonal filters list.
  609. env_filter->RemoveHandler(f1.get());
  610. // Dispatches events.
  611. details = sink->OnEventFromSource(&key_event);
  612. ASSERT_FALSE(details.dispatcher_destroyed);
  613. details = sink->OnEventFromSource(&mouse_pressed);
  614. ASSERT_FALSE(details.dispatcher_destroyed);
  615. // f1 should get no events since it's out and f2 should get them.
  616. EXPECT_EQ(0, f1->num_key_events());
  617. EXPECT_EQ(0, f1->num_mouse_events());
  618. EXPECT_EQ(1, f2->num_key_events());
  619. EXPECT_EQ(1, f2->num_mouse_events());
  620. env_filter->RemoveHandler(f2.get());
  621. }
  622. // Touch visually hides the cursor.
  623. TEST_F(WindowManagerTest, UpdateCursorVisibility) {
  624. ui::test::EventGenerator* generator = GetEventGenerator();
  625. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  626. generator->MoveMouseTo(gfx::Point(0, 0));
  627. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  628. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  629. generator->PressTouch();
  630. EXPECT_FALSE(cursor_manager->IsCursorVisible());
  631. EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
  632. generator->MoveMouseTo(gfx::Point(0, 0));
  633. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  634. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  635. generator->ReleaseTouch();
  636. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  637. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  638. }
  639. // Tests cursor visibility on key pressed event.
  640. TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) {
  641. ui::test::EventGenerator* generator = GetEventGenerator();
  642. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  643. // Pressing a key hides the cursor but does not disable mouse events.
  644. generator->PressKey(ui::VKEY_A, ui::EF_NONE);
  645. EXPECT_FALSE(cursor_manager->IsCursorVisible());
  646. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  647. // Moving mouse shows the cursor.
  648. generator->MoveMouseTo(gfx::Point(0, 0));
  649. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  650. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  651. // Releasing a key does does not hide the cursor and does not disable mouse
  652. // events.
  653. generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE);
  654. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  655. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  656. // Pressing a key with mouse button pressed does not hide the cursor and does
  657. // not disable mouse events.
  658. generator->PressLeftButton();
  659. generator->PressKey(ui::VKEY_A, ui::EF_NONE);
  660. generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE);
  661. generator->ReleaseLeftButton();
  662. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  663. EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  664. }
  665. // Test that pressing an accelerator does not hide the cursor.
  666. TEST_F(WindowManagerTest, UpdateCursorVisibilityAccelerator) {
  667. ui::test::EventGenerator* generator = GetEventGenerator();
  668. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  669. ASSERT_TRUE(cursor_manager->IsCursorVisible());
  670. // Press Ctrl+A, release A first.
  671. generator->PressKey(ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN);
  672. generator->PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
  673. generator->ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
  674. generator->ReleaseKey(ui::VKEY_CONTROL, ui::EF_NONE);
  675. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  676. // Press Ctrl+A, release Ctrl first.
  677. generator->PressKey(ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN);
  678. generator->PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
  679. generator->ReleaseKey(ui::VKEY_CONTROL, ui::EF_NONE);
  680. generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE);
  681. EXPECT_TRUE(cursor_manager->IsCursorVisible());
  682. }
  683. TEST_F(WindowManagerTest, TestCursorClientObserver) {
  684. ui::test::EventGenerator* generator = GetEventGenerator();
  685. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  686. std::unique_ptr<aura::Window> w1 = TestWindowBuilder()
  687. .SetColorWindowDelegate(SK_ColorWHITE)
  688. .SetBounds(gfx::Rect(0, 0, 100, 100))
  689. .Build();
  690. wm::ActivateWindow(w1.get());
  691. // Add two observers. Both should have OnCursorVisibilityChanged()
  692. // invoked when an event changes the visibility of the cursor.
  693. ::wm::TestingCursorClientObserver observer_a;
  694. ::wm::TestingCursorClientObserver observer_b;
  695. cursor_manager->AddObserver(&observer_a);
  696. cursor_manager->AddObserver(&observer_b);
  697. // Initial state before any events have been sent.
  698. observer_a.reset();
  699. observer_b.reset();
  700. EXPECT_FALSE(observer_a.did_visibility_change());
  701. EXPECT_FALSE(observer_b.did_visibility_change());
  702. EXPECT_FALSE(observer_a.is_cursor_visible());
  703. EXPECT_FALSE(observer_b.is_cursor_visible());
  704. EXPECT_FALSE(observer_a.did_cursor_size_change());
  705. EXPECT_FALSE(observer_b.did_cursor_size_change());
  706. // Keypress should hide the cursor.
  707. generator->PressKey(ui::VKEY_A, ui::EF_NONE);
  708. EXPECT_TRUE(observer_a.did_visibility_change());
  709. EXPECT_TRUE(observer_b.did_visibility_change());
  710. EXPECT_FALSE(observer_a.is_cursor_visible());
  711. EXPECT_FALSE(observer_b.is_cursor_visible());
  712. // Set cursor set.
  713. cursor_manager->SetCursorSize(ui::CursorSize::kLarge);
  714. EXPECT_TRUE(observer_a.did_cursor_size_change());
  715. EXPECT_EQ(ui::CursorSize::kLarge, observer_a.cursor_size());
  716. EXPECT_TRUE(observer_b.did_cursor_size_change());
  717. EXPECT_EQ(ui::CursorSize::kLarge, observer_b.cursor_size());
  718. // Mouse move should show the cursor.
  719. observer_a.reset();
  720. observer_b.reset();
  721. generator->MoveMouseTo(50, 50);
  722. EXPECT_TRUE(observer_a.did_visibility_change());
  723. EXPECT_TRUE(observer_b.did_visibility_change());
  724. EXPECT_TRUE(observer_a.is_cursor_visible());
  725. EXPECT_TRUE(observer_b.is_cursor_visible());
  726. // Remove observer_b. Its OnCursorVisibilityChanged() should
  727. // not be invoked past this point.
  728. cursor_manager->RemoveObserver(&observer_b);
  729. // Gesture tap should hide the cursor.
  730. observer_a.reset();
  731. observer_b.reset();
  732. generator->GestureTapAt(gfx::Point(25, 25));
  733. EXPECT_TRUE(observer_a.did_visibility_change());
  734. EXPECT_FALSE(observer_b.did_visibility_change());
  735. EXPECT_FALSE(observer_a.is_cursor_visible());
  736. // Set back cursor set to normal.
  737. cursor_manager->SetCursorSize(ui::CursorSize::kNormal);
  738. EXPECT_TRUE(observer_a.did_cursor_size_change());
  739. EXPECT_EQ(ui::CursorSize::kNormal, observer_a.cursor_size());
  740. EXPECT_FALSE(observer_b.did_cursor_size_change());
  741. // Mouse move should show the cursor.
  742. observer_a.reset();
  743. observer_b.reset();
  744. generator->MoveMouseTo(50, 50);
  745. EXPECT_TRUE(observer_a.did_visibility_change());
  746. EXPECT_FALSE(observer_b.did_visibility_change());
  747. EXPECT_TRUE(observer_a.is_cursor_visible());
  748. cursor_manager->RemoveObserver(&observer_a);
  749. }
  750. } // namespace ash