pointer_unittest.cc 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/exo/pointer.h"
  5. #include "ash/constants/app_types.h"
  6. #include "ash/public/cpp/shell_window_ids.h"
  7. #include "ash/shell.h"
  8. #include "ash/wm/desks/desks_util.h"
  9. #include "ash/wm/window_positioning_utils.h"
  10. #include "base/bind.h"
  11. #include "base/run_loop.h"
  12. #include "base/test/scoped_feature_list.h"
  13. #include "build/chromeos_buildflags.h"
  14. #include "chromeos/ui/base/window_properties.h"
  15. #include "components/exo/buffer.h"
  16. #include "components/exo/data_source.h"
  17. #include "components/exo/data_source_delegate.h"
  18. #include "components/exo/pointer_constraint_delegate.h"
  19. #include "components/exo/pointer_delegate.h"
  20. #include "components/exo/pointer_stylus_delegate.h"
  21. #include "components/exo/relative_pointer_delegate.h"
  22. #include "components/exo/seat.h"
  23. #include "components/exo/shell_surface.h"
  24. #include "components/exo/sub_surface.h"
  25. #include "components/exo/surface.h"
  26. #include "components/exo/test/exo_test_base.h"
  27. #include "components/exo/test/exo_test_data_exchange_delegate.h"
  28. #include "components/exo/test/exo_test_helper.h"
  29. #include "components/exo/test/mock_security_delegate.h"
  30. #include "components/exo/test/shell_surface_builder.h"
  31. #include "components/viz/common/quads/compositor_frame.h"
  32. #include "components/viz/service/surfaces/surface.h"
  33. #include "components/viz/service/surfaces/surface_manager.h"
  34. #include "testing/gmock/include/gmock/gmock.h"
  35. #include "ui/aura/client/aura_constants.h"
  36. #include "ui/aura/client/cursor_client.h"
  37. #include "ui/aura/client/focus_client.h"
  38. #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
  39. #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
  40. #include "ui/events/base_event_utils.h"
  41. #include "ui/events/event.h"
  42. #include "ui/events/event_utils.h"
  43. #include "ui/events/test/event_generator.h"
  44. #include "ui/events/types/event_type.h"
  45. #include "ui/gfx/geometry/vector2d_f.h"
  46. #include "ui/views/widget/widget.h"
  47. #if BUILDFLAG(IS_CHROMEOS_ASH)
  48. #include "ash/constants/ash_features.h"
  49. #include "ash/drag_drop/drag_drop_controller.h"
  50. #include "base/test/bind.h"
  51. #include "components/exo/wm_helper.h"
  52. #include "ui/aura/client/drag_drop_client.h"
  53. #include "ui/aura/window_tree_host.h"
  54. #include "ui/events/test/events_test_utils.h"
  55. #endif
  56. using ::testing::_;
  57. using ::testing::AnyNumber;
  58. namespace exo {
  59. namespace {
  60. void DispatchGesture(ui::EventType gesture_type, gfx::Point location) {
  61. ui::GestureEventDetails event_details(gesture_type);
  62. ui::GestureEvent gesture_event(location.x(), location.y(), 0,
  63. ui::EventTimeForNow(), event_details);
  64. ui::EventSource* event_source =
  65. ash::Shell::GetPrimaryRootWindow()->GetHost()->GetEventSource();
  66. ui::EventSourceTestApi event_source_test(event_source);
  67. ui::EventDispatchDetails details =
  68. event_source_test.SendEventToSink(&gesture_event);
  69. CHECK(!details.dispatcher_destroyed);
  70. }
  71. class MockPointerDelegate : public PointerDelegate {
  72. public:
  73. MockPointerDelegate() {}
  74. // Overridden from PointerDelegate:
  75. MOCK_METHOD1(OnPointerDestroying, void(Pointer*));
  76. MOCK_CONST_METHOD1(CanAcceptPointerEventsForSurface, bool(Surface*));
  77. MOCK_METHOD3(OnPointerEnter, void(Surface*, const gfx::PointF&, int));
  78. MOCK_METHOD1(OnPointerLeave, void(Surface*));
  79. MOCK_METHOD2(OnPointerMotion, void(base::TimeTicks, const gfx::PointF&));
  80. MOCK_METHOD3(OnPointerButton, void(base::TimeTicks, int, bool));
  81. MOCK_METHOD3(OnPointerScroll,
  82. void(base::TimeTicks, const gfx::Vector2dF&, bool));
  83. MOCK_METHOD1(OnPointerScrollStop, void(base::TimeTicks));
  84. MOCK_METHOD0(OnPointerFrame, void());
  85. };
  86. class MockRelativePointerDelegate : public RelativePointerDelegate {
  87. public:
  88. MockRelativePointerDelegate() = default;
  89. ~MockRelativePointerDelegate() = default;
  90. // Overridden from RelativePointerDelegate:
  91. MOCK_METHOD1(OnPointerDestroying, void(Pointer*));
  92. MOCK_METHOD3(OnPointerRelativeMotion,
  93. void(base::TimeTicks,
  94. const gfx::Vector2dF&,
  95. const gfx::Vector2dF&));
  96. };
  97. class MockPointerConstraintDelegate : public PointerConstraintDelegate {
  98. public:
  99. MockPointerConstraintDelegate() {
  100. ON_CALL(*this, OnConstraintActivated).WillByDefault([this]() {
  101. activated_count++;
  102. });
  103. ON_CALL(*this, OnConstraintBroken).WillByDefault([this]() {
  104. broken_count++;
  105. });
  106. }
  107. ~MockPointerConstraintDelegate() = default;
  108. // Overridden from PointerConstraintDelegate:
  109. MOCK_METHOD0(OnConstraintActivated, void());
  110. MOCK_METHOD0(OnAlreadyConstrained, void());
  111. MOCK_METHOD0(OnConstraintBroken, void());
  112. MOCK_METHOD0(IsPersistent, bool());
  113. MOCK_METHOD0(GetConstrainedSurface, Surface*());
  114. MOCK_METHOD0(OnDefunct, void());
  115. int activated_count = 0;
  116. int broken_count = 0;
  117. };
  118. class MockPointerStylusDelegate : public PointerStylusDelegate {
  119. public:
  120. MockPointerStylusDelegate() {}
  121. // Overridden from PointerStylusDelegate:
  122. MOCK_METHOD(void, OnPointerDestroying, (Pointer*));
  123. MOCK_METHOD(void, OnPointerToolChange, (ui::EventPointerType));
  124. MOCK_METHOD(void, OnPointerForce, (base::TimeTicks, float));
  125. MOCK_METHOD(void, OnPointerTilt, (base::TimeTicks, const gfx::Vector2dF&));
  126. };
  127. class TestDataSourceDelegate : public DataSourceDelegate {
  128. public:
  129. TestDataSourceDelegate() {}
  130. TestDataSourceDelegate(const TestDataSourceDelegate&) = delete;
  131. TestDataSourceDelegate& operator=(const TestDataSourceDelegate&) = delete;
  132. // Overridden from DataSourceDelegate:
  133. void OnDataSourceDestroying(DataSource* device) override {}
  134. void OnTarget(const absl::optional<std::string>& mime_type) override {}
  135. void OnSend(const std::string& mime_type, base::ScopedFD fd) override {}
  136. void OnCancelled() override {}
  137. void OnDndDropPerformed() override {}
  138. void OnDndFinished() override {}
  139. void OnAction(DndAction dnd_action) override {}
  140. bool CanAcceptDataEventsForSurface(Surface* surface) const override {
  141. return true;
  142. }
  143. };
  144. class PointerTest : public test::ExoTestBase {
  145. public:
  146. PointerTest() = default;
  147. PointerTest(const PointerTest&) = delete;
  148. PointerTest& operator=(const PointerTest&) = delete;
  149. void SetUp() override {
  150. test::ExoTestBase::SetUp();
  151. // Sometimes underlying infra (i.e. X11 / Xvfb) may emit pointer events
  152. // which can break MockPointerDelegate's expectations, so they should be
  153. // consumed before starting. See https://crbug.com/854674.
  154. base::RunLoop().RunUntilIdle();
  155. }
  156. };
  157. #if BUILDFLAG(IS_CHROMEOS_ASH)
  158. class PointerConstraintTest : public PointerTest {
  159. public:
  160. PointerConstraintTest() = default;
  161. PointerConstraintTest(const PointerConstraintTest&) = delete;
  162. PointerConstraintTest& operator=(const PointerConstraintTest&) = delete;
  163. void SetUp() override {
  164. PointerTest::SetUp();
  165. shell_surface_ = BuildShellSurfaceWhichPermitsPointerLock();
  166. surface_ = shell_surface_->surface_for_testing();
  167. seat_ = std::make_unique<Seat>();
  168. pointer_ = std::make_unique<Pointer>(&delegate_, seat_.get());
  169. focus_client_ =
  170. aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
  171. focus_client_->FocusWindow(surface_->window());
  172. generator_ = std::make_unique<ui::test::EventGenerator>(
  173. ash::Shell::GetPrimaryRootWindow());
  174. EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(surface_))
  175. .WillRepeatedly(testing::Return(true));
  176. EXPECT_CALL(constraint_delegate_, GetConstrainedSurface())
  177. .WillRepeatedly(testing::Return(surface_));
  178. }
  179. void TearDown() override {
  180. // Many objects need to be destroyed before teardown for various reasons.
  181. seat_.reset();
  182. shell_surface_.reset();
  183. surface_ = nullptr;
  184. // Some tests generate mouse events which Pointer::OnMouseEvent() handles
  185. // during the run loop. That routine accesses WMHelper. So, make sure any
  186. // such pending tasks finish before TearDown() destroys the WMHelper.
  187. base::RunLoop().RunUntilIdle();
  188. PointerTest::TearDown();
  189. }
  190. std::unique_ptr<ShellSurface> BuildShellSurfaceWhichPermitsPointerLock() {
  191. std::unique_ptr<ShellSurface> shell_surface =
  192. test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  193. shell_surface->GetWidget()->GetNativeWindow()->SetProperty(
  194. chromeos::kUseOverviewToExitPointerLock, true);
  195. return shell_surface;
  196. }
  197. std::unique_ptr<ui::test::EventGenerator> generator_;
  198. std::unique_ptr<Pointer> pointer_;
  199. std::unique_ptr<Seat> seat_;
  200. testing::NiceMock<MockPointerConstraintDelegate> constraint_delegate_;
  201. testing::NiceMock<MockPointerDelegate> delegate_;
  202. std::unique_ptr<ShellSurface> shell_surface_;
  203. Surface* surface_;
  204. aura::client::FocusClient* focus_client_;
  205. };
  206. #endif
  207. TEST_F(PointerTest, SetCursor) {
  208. std::unique_ptr<Surface> surface(new Surface);
  209. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  210. gfx::Size buffer_size(10, 10);
  211. std::unique_ptr<Buffer> buffer(
  212. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  213. surface->Attach(buffer.get());
  214. surface->Commit();
  215. MockPointerDelegate delegate;
  216. Seat seat;
  217. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  218. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  219. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  220. .WillRepeatedly(testing::Return(true));
  221. EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  222. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  223. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  224. std::unique_ptr<Surface> pointer_surface(new Surface);
  225. std::unique_ptr<Buffer> pointer_buffer(
  226. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  227. pointer_surface->Attach(pointer_buffer.get());
  228. pointer_surface->Commit();
  229. // Set pointer surface.
  230. pointer->SetCursor(pointer_surface.get(), gfx::Point(5, 5));
  231. base::RunLoop().RunUntilIdle();
  232. const viz::CompositorRenderPass* last_render_pass;
  233. {
  234. viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId();
  235. viz::SurfaceManager* surface_manager = GetSurfaceManager();
  236. ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
  237. const viz::CompositorFrame& frame =
  238. surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
  239. EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
  240. frame.render_pass_list.back()->output_rect);
  241. last_render_pass = frame.render_pass_list.back().get();
  242. }
  243. // Adjust hotspot.
  244. pointer->SetCursor(pointer_surface.get(), gfx::Point());
  245. base::RunLoop().RunUntilIdle();
  246. // Verify that adjustment to hotspot resulted in new frame.
  247. {
  248. viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId();
  249. viz::SurfaceManager* surface_manager = GetSurfaceManager();
  250. ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
  251. const viz::CompositorFrame& frame =
  252. surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
  253. EXPECT_TRUE(frame.render_pass_list.back().get() != last_render_pass);
  254. }
  255. // Unset pointer surface.
  256. pointer->SetCursor(nullptr, gfx::Point());
  257. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  258. pointer.reset();
  259. }
  260. TEST_F(PointerTest, SetCursorNull) {
  261. std::unique_ptr<Surface> surface(new Surface);
  262. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  263. gfx::Size buffer_size(10, 10);
  264. std::unique_ptr<Buffer> buffer(
  265. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  266. surface->Attach(buffer.get());
  267. surface->Commit();
  268. MockPointerDelegate delegate;
  269. Seat seat;
  270. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  271. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  272. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  273. .WillRepeatedly(testing::Return(true));
  274. EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  275. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  276. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  277. pointer->SetCursor(nullptr, gfx::Point());
  278. base::RunLoop().RunUntilIdle();
  279. EXPECT_EQ(nullptr, pointer->root_surface());
  280. aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
  281. shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  282. EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client->GetCursor().type());
  283. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  284. pointer.reset();
  285. }
  286. TEST_F(PointerTest, SetCursorType) {
  287. std::unique_ptr<Surface> surface(new Surface);
  288. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  289. gfx::Size buffer_size(10, 10);
  290. std::unique_ptr<Buffer> buffer(
  291. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  292. surface->Attach(buffer.get());
  293. surface->Commit();
  294. MockPointerDelegate delegate;
  295. Seat seat;
  296. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  297. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  298. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  299. .WillRepeatedly(testing::Return(true));
  300. EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  301. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  302. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  303. pointer->SetCursorType(ui::mojom::CursorType::kIBeam);
  304. base::RunLoop().RunUntilIdle();
  305. EXPECT_EQ(nullptr, pointer->root_surface());
  306. aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
  307. shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  308. EXPECT_EQ(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());
  309. // Set the pointer with surface after setting pointer type.
  310. std::unique_ptr<Surface> pointer_surface(new Surface);
  311. std::unique_ptr<Buffer> pointer_buffer(
  312. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  313. pointer_surface->Attach(pointer_buffer.get());
  314. pointer_surface->Commit();
  315. pointer->SetCursor(pointer_surface.get(), gfx::Point());
  316. base::RunLoop().RunUntilIdle();
  317. {
  318. viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId();
  319. viz::SurfaceManager* surface_manager = GetSurfaceManager();
  320. ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
  321. const viz::CompositorFrame& frame =
  322. surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
  323. EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
  324. frame.render_pass_list.back()->output_rect);
  325. }
  326. // Set the pointer type after the pointer surface is specified.
  327. pointer->SetCursorType(ui::mojom::CursorType::kCross);
  328. base::RunLoop().RunUntilIdle();
  329. EXPECT_EQ(nullptr, pointer->root_surface());
  330. EXPECT_EQ(ui::mojom::CursorType::kCross, cursor_client->GetCursor().type());
  331. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  332. pointer.reset();
  333. }
  334. TEST_F(PointerTest, SetCursorTypeOutsideOfSurface) {
  335. std::unique_ptr<Surface> surface(new Surface);
  336. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  337. gfx::Size buffer_size(10, 10);
  338. std::unique_ptr<Buffer> buffer(
  339. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  340. surface->Attach(buffer.get());
  341. surface->Commit();
  342. MockPointerDelegate delegate;
  343. Seat seat;
  344. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  345. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  346. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  347. .WillRepeatedly(testing::Return(true));
  348. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() -
  349. gfx::Vector2d(1, 1));
  350. pointer->SetCursorType(ui::mojom::CursorType::kIBeam);
  351. base::RunLoop().RunUntilIdle();
  352. EXPECT_EQ(nullptr, pointer->root_surface());
  353. aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
  354. shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  355. // The cursor type shouldn't be the specified one, since the pointer is
  356. // located outside of the surface.
  357. EXPECT_NE(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());
  358. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  359. pointer.reset();
  360. }
  361. TEST_F(PointerTest, SetCursorAndSetCursorType) {
  362. std::unique_ptr<Surface> surface(new Surface);
  363. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  364. gfx::Size buffer_size(10, 10);
  365. std::unique_ptr<Buffer> buffer(
  366. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  367. surface->Attach(buffer.get());
  368. surface->Commit();
  369. MockPointerDelegate delegate;
  370. Seat seat;
  371. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  372. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  373. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  374. .WillRepeatedly(testing::Return(true));
  375. EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  376. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  377. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  378. std::unique_ptr<Surface> pointer_surface(new Surface);
  379. std::unique_ptr<Buffer> pointer_buffer(
  380. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  381. pointer_surface->Attach(pointer_buffer.get());
  382. pointer_surface->Commit();
  383. // Set pointer surface.
  384. pointer->SetCursor(pointer_surface.get(), gfx::Point());
  385. EXPECT_EQ(1u, pointer->GetActivePresentationCallbacksForTesting().size());
  386. base::RunLoop().RunUntilIdle();
  387. {
  388. viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId();
  389. viz::SurfaceManager* surface_manager = GetSurfaceManager();
  390. ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
  391. const viz::CompositorFrame& frame =
  392. surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
  393. EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
  394. frame.render_pass_list.back()->output_rect);
  395. }
  396. // Set the cursor type to the kNone through SetCursorType.
  397. pointer->SetCursorType(ui::mojom::CursorType::kNone);
  398. EXPECT_TRUE(pointer->GetActivePresentationCallbacksForTesting().empty());
  399. base::RunLoop().RunUntilIdle();
  400. EXPECT_EQ(nullptr, pointer->root_surface());
  401. // Set the same pointer surface again.
  402. pointer->SetCursor(pointer_surface.get(), gfx::Point());
  403. EXPECT_EQ(1u, pointer->GetActivePresentationCallbacksForTesting().size());
  404. auto& list =
  405. pointer->GetActivePresentationCallbacksForTesting().begin()->second;
  406. base::RunLoop runloop;
  407. list.push_back(base::BindRepeating(
  408. [](base::RepeatingClosure callback, const gfx::PresentationFeedback&) {
  409. callback.Run();
  410. },
  411. runloop.QuitClosure()));
  412. runloop.Run();
  413. {
  414. viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId();
  415. viz::SurfaceManager* surface_manager = GetSurfaceManager();
  416. ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
  417. const viz::CompositorFrame& frame =
  418. surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
  419. EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
  420. frame.render_pass_list.back()->output_rect);
  421. }
  422. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  423. pointer.reset();
  424. }
  425. TEST_F(PointerTest, SetCursorNullAndSetCursorType) {
  426. std::unique_ptr<Surface> surface(new Surface);
  427. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  428. gfx::Size buffer_size(10, 10);
  429. std::unique_ptr<Buffer> buffer(
  430. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  431. surface->Attach(buffer.get());
  432. surface->Commit();
  433. MockPointerDelegate delegate;
  434. Seat seat;
  435. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  436. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  437. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  438. .WillRepeatedly(testing::Return(true));
  439. EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  440. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  441. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  442. // Set nullptr surface.
  443. pointer->SetCursor(nullptr, gfx::Point());
  444. base::RunLoop().RunUntilIdle();
  445. EXPECT_EQ(nullptr, pointer->root_surface());
  446. aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
  447. shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  448. EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client->GetCursor().type());
  449. // Set the cursor type.
  450. pointer->SetCursorType(ui::mojom::CursorType::kIBeam);
  451. base::RunLoop().RunUntilIdle();
  452. EXPECT_EQ(nullptr, pointer->root_surface());
  453. EXPECT_EQ(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());
  454. // Set nullptr surface again.
  455. pointer->SetCursor(nullptr, gfx::Point());
  456. base::RunLoop().RunUntilIdle();
  457. EXPECT_EQ(nullptr, pointer->root_surface());
  458. EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client->GetCursor().type());
  459. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  460. pointer.reset();
  461. }
  462. TEST_F(PointerTest, OnPointerEnter) {
  463. std::unique_ptr<Surface> surface(new Surface);
  464. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  465. gfx::Size buffer_size(10, 10);
  466. std::unique_ptr<Buffer> buffer(
  467. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  468. surface->Attach(buffer.get());
  469. surface->Commit();
  470. MockPointerDelegate delegate;
  471. Seat seat;
  472. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  473. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  474. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  475. .WillRepeatedly(testing::Return(true));
  476. EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  477. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  478. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  479. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  480. pointer.reset();
  481. }
  482. TEST_F(PointerTest, OnPointerLeave) {
  483. std::unique_ptr<Surface> surface(new Surface);
  484. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  485. gfx::Size buffer_size(10, 10);
  486. std::unique_ptr<Buffer> buffer(
  487. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  488. surface->Attach(buffer.get());
  489. surface->Commit();
  490. MockPointerDelegate delegate;
  491. Seat seat;
  492. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  493. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  494. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  495. .WillRepeatedly(testing::Return(true));
  496. EXPECT_CALL(delegate, OnPointerFrame()).Times(4);
  497. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  498. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  499. EXPECT_CALL(delegate, OnPointerLeave(surface.get()));
  500. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().bottom_right());
  501. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  502. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  503. EXPECT_CALL(delegate, OnPointerLeave(surface.get()));
  504. shell_surface.reset();
  505. surface.reset();
  506. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  507. pointer.reset();
  508. }
  509. TEST_F(PointerTest, OnPointerMotion) {
  510. std::unique_ptr<Surface> surface(new Surface);
  511. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  512. gfx::Size buffer_size(10, 10);
  513. std::unique_ptr<Buffer> buffer(
  514. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  515. surface->Attach(buffer.get());
  516. surface->Commit();
  517. MockPointerDelegate delegate;
  518. Seat seat;
  519. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  520. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  521. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  522. .WillRepeatedly(testing::Return(true));
  523. EXPECT_CALL(delegate, OnPointerFrame()).Times(6);
  524. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  525. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  526. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  527. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() +
  528. gfx::Vector2d(1, 1));
  529. std::unique_ptr<Surface> sub_surface(new Surface);
  530. std::unique_ptr<SubSurface> sub(
  531. new SubSurface(sub_surface.get(), surface.get()));
  532. surface->SetSubSurfacePosition(sub_surface.get(), gfx::PointF(5, 5));
  533. gfx::Size sub_buffer_size(5, 5);
  534. std::unique_ptr<Buffer> sub_buffer(
  535. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(sub_buffer_size)));
  536. sub_surface->Attach(sub_buffer.get());
  537. sub_surface->Commit();
  538. surface->Commit();
  539. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(sub_surface.get()))
  540. .WillRepeatedly(testing::Return(true));
  541. EXPECT_CALL(delegate, OnPointerLeave(surface.get()));
  542. EXPECT_CALL(delegate, OnPointerEnter(sub_surface.get(), gfx::PointF(), 0));
  543. generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin());
  544. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  545. generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin() +
  546. gfx::Vector2d(1, 1));
  547. std::unique_ptr<Surface> child_surface(new Surface);
  548. std::unique_ptr<ShellSurface> child_shell_surface(new ShellSurface(
  549. child_surface.get(), gfx::Point(9, 9), /*can_minimize=*/false,
  550. ash::desks_util::GetActiveDeskContainerId()));
  551. child_shell_surface->DisableMovement();
  552. child_shell_surface->SetParent(shell_surface.get());
  553. gfx::Size child_buffer_size(15, 15);
  554. std::unique_ptr<Buffer> child_buffer(
  555. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size)));
  556. child_surface->Attach(child_buffer.get());
  557. child_surface->Commit();
  558. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(child_surface.get()))
  559. .WillRepeatedly(testing::Return(true));
  560. EXPECT_CALL(delegate, OnPointerLeave(sub_surface.get()));
  561. EXPECT_CALL(delegate, OnPointerEnter(child_surface.get(), gfx::PointF(), 0));
  562. generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin());
  563. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(10, 10)));
  564. generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin() +
  565. gfx::Vector2d(10, 10));
  566. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  567. pointer.reset();
  568. }
  569. TEST_F(PointerTest, OnPointerButton) {
  570. std::unique_ptr<Surface> surface(new Surface);
  571. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  572. gfx::Size buffer_size(10, 10);
  573. std::unique_ptr<Buffer> buffer(
  574. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  575. surface->Attach(buffer.get());
  576. surface->Commit();
  577. MockPointerDelegate delegate;
  578. Seat seat;
  579. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  580. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  581. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  582. .WillRepeatedly(testing::Return(true));
  583. EXPECT_CALL(delegate, OnPointerFrame()).Times(3);
  584. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  585. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  586. EXPECT_CALL(delegate,
  587. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
  588. EXPECT_CALL(delegate,
  589. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
  590. generator.ClickLeftButton();
  591. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  592. pointer.reset();
  593. }
  594. TEST_F(PointerTest, OnPointerScroll) {
  595. std::unique_ptr<Surface> surface(new Surface);
  596. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  597. gfx::Size buffer_size(10, 10);
  598. std::unique_ptr<Buffer> buffer(
  599. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  600. surface->Attach(buffer.get());
  601. surface->Commit();
  602. MockPointerDelegate delegate;
  603. Seat seat;
  604. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  605. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  606. gfx::Point location = surface->window()->GetBoundsInScreen().origin();
  607. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  608. .WillRepeatedly(testing::Return(true));
  609. EXPECT_CALL(delegate, OnPointerFrame()).Times(3);
  610. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  611. generator.MoveMouseTo(location);
  612. {
  613. // Expect fling stop followed by scroll and scroll stop.
  614. testing::InSequence sequence;
  615. EXPECT_CALL(delegate,
  616. OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false));
  617. EXPECT_CALL(delegate, OnPointerScrollStop(testing::_));
  618. }
  619. generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1, 1);
  620. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  621. pointer.reset();
  622. }
  623. TEST_F(PointerTest, OnPointerScrollWithThreeFinger) {
  624. std::unique_ptr<Surface> surface(new Surface);
  625. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  626. gfx::Size buffer_size(10, 10);
  627. std::unique_ptr<Buffer> buffer(
  628. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  629. surface->Attach(buffer.get());
  630. surface->Commit();
  631. MockPointerDelegate delegate;
  632. Seat seat;
  633. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  634. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  635. gfx::Point location = surface->window()->GetBoundsInScreen().origin();
  636. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  637. .WillRepeatedly(testing::Return(true));
  638. EXPECT_CALL(delegate, OnPointerFrame()).Times(2);
  639. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  640. generator.MoveMouseTo(location);
  641. {
  642. // Expect no scroll.
  643. testing::InSequence sequence;
  644. EXPECT_CALL(delegate, OnPointerScrollStop(testing::_));
  645. }
  646. // Three fingers scroll.
  647. generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1,
  648. 3 /* num_fingers */);
  649. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  650. pointer.reset();
  651. }
  652. TEST_F(PointerTest, OnPointerScrollDiscrete) {
  653. std::unique_ptr<Surface> surface(new Surface);
  654. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  655. gfx::Size buffer_size(10, 10);
  656. std::unique_ptr<Buffer> buffer(
  657. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  658. surface->Attach(buffer.get());
  659. surface->Commit();
  660. MockPointerDelegate delegate;
  661. Seat seat;
  662. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  663. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  664. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  665. .WillRepeatedly(testing::Return(true));
  666. EXPECT_CALL(delegate, OnPointerFrame()).Times(2);
  667. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  668. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  669. EXPECT_CALL(delegate,
  670. OnPointerScroll(testing::_, gfx::Vector2dF(1, 1), true));
  671. generator.MoveMouseWheel(1, 1);
  672. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  673. pointer.reset();
  674. }
  675. TEST_F(PointerTest, RegisterPointerEventsOnModal) {
  676. // Create modal surface.
  677. std::unique_ptr<Surface> surface(new Surface);
  678. std::unique_ptr<ShellSurface> shell_surface(
  679. new ShellSurface(surface.get(), gfx::Point(), /*can_minimize=*/false,
  680. ash::kShellWindowId_SystemModalContainer));
  681. shell_surface->DisableMovement();
  682. std::unique_ptr<Buffer> buffer(
  683. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5))));
  684. surface->Attach(buffer.get());
  685. surface->Commit();
  686. ash::CenterWindow(shell_surface->GetWidget()->GetNativeWindow());
  687. // Make the window modal.
  688. shell_surface->SetSystemModal(true);
  689. EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());
  690. MockPointerDelegate delegate;
  691. Seat seat;
  692. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  693. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  694. EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  695. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  696. .WillRepeatedly(testing::Return(true));
  697. // Pointer events on modal window should be registered.
  698. gfx::Point origin = surface->window()->GetBoundsInScreen().origin();
  699. {
  700. testing::InSequence sequence;
  701. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  702. generator.MoveMouseTo(origin);
  703. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  704. generator.MoveMouseTo(origin + gfx::Vector2d(1, 1));
  705. EXPECT_CALL(delegate,
  706. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
  707. EXPECT_CALL(delegate,
  708. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
  709. generator.ClickLeftButton();
  710. EXPECT_CALL(delegate,
  711. OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false));
  712. EXPECT_CALL(delegate, OnPointerScrollStop(testing::_));
  713. generator.ScrollSequence(origin, base::TimeDelta(), 1, 1, 1, 1);
  714. }
  715. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  716. pointer.reset();
  717. }
  718. TEST_F(PointerTest, IgnorePointerEventsOnNonModalWhenModalIsOpen) {
  719. // Create surface for non-modal window.
  720. std::unique_ptr<Surface> surface(new Surface);
  721. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  722. std::unique_ptr<Buffer> buffer(
  723. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10))));
  724. surface->Attach(buffer.get());
  725. surface->Commit();
  726. // Create surface for modal window.
  727. std::unique_ptr<Surface> surface2(new Surface);
  728. std::unique_ptr<ShellSurface> shell_surface2(
  729. new ShellSurface(surface2.get(), gfx::Point(), /*can_minimize=*/false,
  730. ash::kShellWindowId_SystemModalContainer));
  731. shell_surface2->DisableMovement();
  732. std::unique_ptr<Buffer> buffer2(
  733. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5))));
  734. surface2->Attach(buffer2.get());
  735. surface2->Commit();
  736. ash::CenterWindow(shell_surface2->GetWidget()->GetNativeWindow());
  737. // Make the window modal.
  738. shell_surface2->SetSystemModal(true);
  739. EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());
  740. MockPointerDelegate delegate;
  741. Seat seat;
  742. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  743. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  744. EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  745. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  746. .WillRepeatedly(testing::Return(true));
  747. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface2.get()))
  748. .WillRepeatedly(testing::Return(true));
  749. // Check if pointer events on non-modal window are ignored.
  750. gfx::Point nonModalOrigin = surface->window()->GetBoundsInScreen().origin();
  751. {
  752. testing::InSequence sequence;
  753. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0))
  754. .Times(0);
  755. generator.MoveMouseTo(nonModalOrigin);
  756. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)))
  757. .Times(0);
  758. generator.MoveMouseTo(nonModalOrigin + gfx::Vector2d(1, 1));
  759. EXPECT_CALL(delegate,
  760. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true))
  761. .Times(0);
  762. EXPECT_CALL(delegate,
  763. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false))
  764. .Times(0);
  765. generator.ClickLeftButton();
  766. EXPECT_CALL(delegate,
  767. OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false))
  768. .Times(0);
  769. EXPECT_CALL(delegate, OnPointerScrollStop(testing::_)).Times(0);
  770. generator.ScrollSequence(nonModalOrigin, base::TimeDelta(), 1, 1, 1, 1);
  771. EXPECT_CALL(delegate, OnPointerLeave(surface.get())).Times(0);
  772. generator.MoveMouseTo(
  773. surface->window()->GetBoundsInScreen().bottom_right());
  774. }
  775. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  776. pointer.reset();
  777. }
  778. TEST_F(PointerTest, IgnorePointerLeaveOnModal) {
  779. // Create modal surface.
  780. std::unique_ptr<Surface> surface(new Surface);
  781. std::unique_ptr<ShellSurface> shell_surface(
  782. new ShellSurface(surface.get(), gfx::Point(), /*can_minimize=*/false,
  783. ash::kShellWindowId_SystemModalContainer));
  784. shell_surface->DisableMovement();
  785. std::unique_ptr<Buffer> buffer(
  786. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5))));
  787. surface->Attach(buffer.get());
  788. surface->Commit();
  789. ash::CenterWindow(shell_surface->GetWidget()->GetNativeWindow());
  790. // Make the window modal.
  791. shell_surface->SetSystemModal(true);
  792. EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());
  793. MockPointerDelegate delegate;
  794. Seat seat;
  795. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  796. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  797. EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  798. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  799. .WillRepeatedly(testing::Return(true));
  800. gfx::Point origin = surface->window()->GetBoundsInScreen().origin();
  801. {
  802. testing::InSequence sequence;
  803. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  804. generator.MoveMouseTo(origin);
  805. // OnPointerLeave should not be called on the modal surface when the pointer
  806. // moves out of its bounds.
  807. EXPECT_CALL(delegate, OnPointerLeave(surface.get())).Times(0);
  808. generator.MoveMouseTo(
  809. surface->window()->GetBoundsInScreen().bottom_right());
  810. }
  811. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  812. pointer.reset();
  813. }
  814. TEST_F(PointerTest, RegisterPointerEventsOnNonModal) {
  815. // Create surface for non-modal window.
  816. std::unique_ptr<Surface> surface(new Surface);
  817. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  818. std::unique_ptr<Buffer> buffer(
  819. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10))));
  820. surface->Attach(buffer.get());
  821. surface->Commit();
  822. // Create another surface for a non-modal window.
  823. std::unique_ptr<Surface> surface2(new Surface);
  824. std::unique_ptr<ShellSurface> shell_surface2(
  825. new ShellSurface(surface2.get(), gfx::Point(), /*can_minimize=*/false,
  826. ash::kShellWindowId_SystemModalContainer));
  827. shell_surface2->DisableMovement();
  828. std::unique_ptr<Buffer> buffer2(
  829. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5))));
  830. surface2->Attach(buffer2.get());
  831. surface2->Commit();
  832. ash::CenterWindow(shell_surface2->GetWidget()->GetNativeWindow());
  833. MockPointerDelegate delegate;
  834. Seat seat;
  835. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  836. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  837. EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  838. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  839. .WillRepeatedly(testing::Return(true));
  840. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface2.get()))
  841. .WillRepeatedly(testing::Return(true));
  842. // Ensure second window is non-modal.
  843. shell_surface2->SetSystemModal(false);
  844. EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen());
  845. // Check if pointer events on first non-modal window are registered.
  846. gfx::Point firstWindowOrigin =
  847. surface->window()->GetBoundsInScreen().origin();
  848. {
  849. testing::InSequence sequence;
  850. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  851. generator.MoveMouseTo(firstWindowOrigin);
  852. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  853. generator.MoveMouseTo(firstWindowOrigin + gfx::Vector2d(1, 1));
  854. EXPECT_CALL(delegate,
  855. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
  856. EXPECT_CALL(delegate,
  857. OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
  858. generator.ClickLeftButton();
  859. EXPECT_CALL(delegate,
  860. OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false));
  861. EXPECT_CALL(delegate, OnPointerScrollStop(testing::_));
  862. generator.ScrollSequence(firstWindowOrigin, base::TimeDelta(), 1, 1, 1, 1);
  863. EXPECT_CALL(delegate, OnPointerLeave(surface.get()));
  864. generator.MoveMouseTo(
  865. surface->window()->GetBoundsInScreen().bottom_right());
  866. }
  867. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  868. pointer.reset();
  869. }
  870. TEST_F(PointerTest, DragDropAbort) {
  871. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  872. MockPointerDelegate pointer_delegate;
  873. std::unique_ptr<Pointer> pointer(new Pointer(&pointer_delegate, &seat));
  874. TestDataSourceDelegate data_source_delegate;
  875. DataSource source(&data_source_delegate);
  876. Surface origin, icon;
  877. // Make origin into a real window so the pointer can click it
  878. ShellSurface shell_surface(&origin);
  879. Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)));
  880. origin.Attach(&buffer);
  881. origin.Commit();
  882. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  883. EXPECT_CALL(pointer_delegate, CanAcceptPointerEventsForSurface(&origin))
  884. .WillRepeatedly(testing::Return(true));
  885. EXPECT_CALL(pointer_delegate, OnPointerFrame()).Times(3);
  886. EXPECT_CALL(pointer_delegate, OnPointerEnter(&origin, gfx::PointF(), 0));
  887. generator.MoveMouseTo(origin.window()->GetBoundsInScreen().origin());
  888. seat.StartDrag(&source, &origin, &icon, ui::mojom::DragEventSource::kMouse);
  889. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  890. EXPECT_CALL(pointer_delegate, OnPointerButton).Times(2);
  891. generator.PressLeftButton();
  892. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  893. generator.ReleaseLeftButton();
  894. EXPECT_FALSE(seat.get_drag_drop_operation_for_testing());
  895. EXPECT_CALL(pointer_delegate, OnPointerDestroying(pointer.get()));
  896. pointer.reset();
  897. }
  898. #if BUILDFLAG(IS_CHROMEOS_ASH)
  899. TEST_F(PointerTest, DragDropAndPointerEnterLeaveEvents) {
  900. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  901. MockPointerDelegate pointer_delegate;
  902. std::unique_ptr<Pointer> pointer(new Pointer(&pointer_delegate, &seat));
  903. TestDataSourceDelegate data_source_delegate;
  904. DataSource source(&data_source_delegate);
  905. Surface origin;
  906. // Make origin into a real window so the pointer can click it
  907. ShellSurface shell_surface(&origin);
  908. Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)));
  909. origin.Attach(&buffer);
  910. origin.Commit();
  911. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  912. EXPECT_CALL(pointer_delegate, CanAcceptPointerEventsForSurface(&origin))
  913. .WillRepeatedly(testing::Return(true));
  914. EXPECT_CALL(pointer_delegate, OnPointerFrame()).Times(AnyNumber());
  915. EXPECT_CALL(pointer_delegate, OnPointerEnter(&origin, gfx::PointF(), 0));
  916. generator.MoveMouseTo(origin.window()->GetBoundsInScreen().origin());
  917. auto* drag_drop_controller = static_cast<ash::DragDropController*>(
  918. aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  919. ASSERT_TRUE(drag_drop_controller);
  920. generator.PressLeftButton();
  921. seat.StartDrag(&source, &origin, /*icon=*/nullptr,
  922. ui::mojom::DragEventSource::kMouse);
  923. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  924. // As soon as the runloop gets triggered, emit a mouse release event.
  925. drag_drop_controller->SetLoopClosureForTesting(
  926. base::BindLambdaForTesting([&]() {
  927. EXPECT_CALL(pointer_delegate, OnPointerEnter(_, _, _));
  928. generator.ReleaseLeftButton();
  929. }),
  930. base::DoNothing());
  931. EXPECT_CALL(pointer_delegate, OnPointerLeave(_));
  932. base::RunLoop().RunUntilIdle();
  933. EXPECT_CALL(pointer_delegate, OnPointerDestroying(pointer.get()));
  934. pointer.reset();
  935. }
  936. TEST_F(PointerTest, DragDropAndPointerEnterLeaveEvents_NoOpOnTouchDrag) {
  937. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  938. MockPointerDelegate pointer_delegate;
  939. std::unique_ptr<Pointer> pointer(new Pointer(&pointer_delegate, &seat));
  940. TestDataSourceDelegate data_source_delegate;
  941. DataSource source(&data_source_delegate);
  942. Surface origin;
  943. // Make origin into a real window so the pointer can click it
  944. ShellSurface shell_surface(&origin);
  945. Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)));
  946. origin.Attach(&buffer);
  947. origin.Commit();
  948. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  949. EXPECT_CALL(pointer_delegate, CanAcceptPointerEventsForSurface(&origin))
  950. .WillRepeatedly(testing::Return(true));
  951. EXPECT_CALL(pointer_delegate, OnPointerFrame()).Times(AnyNumber());
  952. EXPECT_CALL(pointer_delegate, OnPointerEnter(&origin, gfx::PointF(), 0));
  953. generator.MoveMouseTo(origin.window()->GetBoundsInScreen().origin());
  954. auto* drag_drop_controller = static_cast<ash::DragDropController*>(
  955. aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  956. ASSERT_TRUE(drag_drop_controller);
  957. seat.StartDrag(&source, &origin, /*icon=*/nullptr,
  958. ui::mojom::DragEventSource::kTouch);
  959. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  960. // Initiate the gesture sequence.
  961. DispatchGesture(ui::ET_GESTURE_BEGIN, gfx::Point(10, 10));
  962. // As soon as the runloop gets triggered, emit a mouse release event.
  963. drag_drop_controller->SetLoopClosureForTesting(
  964. base::BindLambdaForTesting([&]() {
  965. EXPECT_CALL(pointer_delegate, OnPointerEnter(_, _, _)).Times(0);
  966. // generator.ReleaseLeftButton();
  967. generator.set_current_screen_location(gfx::Point(10, 10));
  968. generator.PressMoveAndReleaseTouchBy(50, 50);
  969. }),
  970. base::DoNothing());
  971. EXPECT_CALL(pointer_delegate, OnPointerLeave(_)).Times(0);
  972. base::RunLoop().RunUntilIdle();
  973. EXPECT_CALL(pointer_delegate, OnPointerDestroying(pointer.get()));
  974. pointer.reset();
  975. }
  976. TEST_F(PointerTest, IgnoresHandledEvents) {
  977. // A very dumb handler that simply marks all events as handled. This is needed
  978. // allows us to mark a mouse event as handled as it gets processed by the
  979. // event processor.
  980. class SetHandledHandler : public ui::EventHandler {
  981. void OnMouseEvent(ui::MouseEvent* event) override { event->SetHandled(); }
  982. };
  983. SetHandledHandler handler;
  984. ash::Shell::Get()->AddPreTargetHandler(&handler);
  985. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  986. testing::NiceMock<MockPointerDelegate> pointer_delegate;
  987. std::unique_ptr<Pointer> pointer(new Pointer(&pointer_delegate, &seat));
  988. // Make origin into a real window so the touch can click it
  989. std::unique_ptr<ShellSurface> shell_surface =
  990. test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  991. EXPECT_CALL(pointer_delegate, CanAcceptPointerEventsForSurface(testing::_))
  992. .WillRepeatedly(testing::Return(true));
  993. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  994. // The SetHandlerHandler should have marked the event as processed. Therefore
  995. // the event should simply be ignored.
  996. EXPECT_CALL(pointer_delegate,
  997. OnPointerButton(testing::_, testing::_, testing::_))
  998. .Times(0);
  999. // This event should be ignored because it has already been handled.
  1000. auto window_point = shell_surface->surface_for_testing()
  1001. ->window()
  1002. ->GetBoundsInScreen()
  1003. .CenterPoint();
  1004. generator.MoveMouseTo(window_point);
  1005. generator.ClickLeftButton();
  1006. ash::Shell::Get()->RemovePreTargetHandler(&handler);
  1007. }
  1008. namespace {
  1009. class PointerDragDropObserver : public WMHelper::DragDropObserver {
  1010. public:
  1011. PointerDragDropObserver(DropCallback closure)
  1012. : closure_(std::move(closure)) {}
  1013. private:
  1014. // WMHelper::DragDropObserver overrides:
  1015. void OnDragEntered(const ui::DropTargetEvent& event) override {}
  1016. aura::client::DragUpdateInfo OnDragUpdated(
  1017. const ui::DropTargetEvent& event) override {
  1018. return aura::client::DragUpdateInfo();
  1019. }
  1020. void OnDragExited() override {}
  1021. DropCallback GetDropCallback() override { return std::move(closure_); }
  1022. DropCallback closure_;
  1023. };
  1024. } // namespace
  1025. // Test for crbug.com/1307143: It ensures no "pointer enter" event is
  1026. // processed in case the target surface is destroyed during the drop action.
  1027. TEST_F(PointerTest,
  1028. DragDropAndPointerEnterLeaveEvents_NoEnterOnSurfaceDestroy) {
  1029. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  1030. MockPointerDelegate pointer_delegate;
  1031. std::unique_ptr<Pointer> pointer(new Pointer(&pointer_delegate, &seat));
  1032. TestDataSourceDelegate data_source_delegate;
  1033. DataSource source(&data_source_delegate);
  1034. std::unique_ptr<Surface> origin(new Surface());
  1035. auto* origin_ptr = origin.get();
  1036. // Make origin into a real window so the pointer can click it
  1037. ShellSurface shell_surface(origin_ptr);
  1038. Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)));
  1039. origin_ptr->Attach(&buffer);
  1040. origin_ptr->Commit();
  1041. auto closure = base::BindOnce([](std::unique_ptr<Surface> shell_surface,
  1042. ui::mojom::DragOperation& output_drag_op) {},
  1043. std::move(origin));
  1044. PointerDragDropObserver drag_drop_observer(std::move(closure));
  1045. auto* wm_helper = WMHelper::GetInstance();
  1046. wm_helper->AddDragDropObserver(&drag_drop_observer);
  1047. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  1048. EXPECT_CALL(pointer_delegate, CanAcceptPointerEventsForSurface(origin_ptr))
  1049. .WillRepeatedly(testing::Return(true));
  1050. EXPECT_CALL(pointer_delegate, OnPointerFrame()).Times(AnyNumber());
  1051. EXPECT_CALL(pointer_delegate, OnPointerEnter(origin_ptr, gfx::PointF(), 0));
  1052. generator.MoveMouseTo(origin_ptr->window()->GetBoundsInScreen().origin());
  1053. auto* drag_drop_controller = static_cast<ash::DragDropController*>(
  1054. aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  1055. ASSERT_TRUE(drag_drop_controller);
  1056. generator.PressLeftButton();
  1057. seat.StartDrag(&source, origin_ptr, /*icon=*/nullptr,
  1058. ui::mojom::DragEventSource::kMouse);
  1059. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  1060. // As soon as the runloop gets triggered, emit a mouse release event.
  1061. drag_drop_controller->SetLoopClosureForTesting(
  1062. base::BindLambdaForTesting([&]() {
  1063. EXPECT_CALL(pointer_delegate, OnPointerEnter(_, _, _));
  1064. generator.ReleaseLeftButton();
  1065. }),
  1066. base::DoNothing());
  1067. // OnPointerLeave() gets called twice:
  1068. // 1/ when the drag starts;
  1069. // 2/ when the dragging window gets destroyed.
  1070. EXPECT_CALL(pointer_delegate, OnPointerLeave(_)).Times(2);
  1071. base::RunLoop().RunUntilIdle();
  1072. wm_helper->RemoveDragDropObserver(&drag_drop_observer);
  1073. EXPECT_CALL(pointer_delegate, OnPointerDestroying(pointer.get()));
  1074. pointer.reset();
  1075. }
  1076. // Test for crbug.com/1307143: It ensures no "pointer enter" event is
  1077. // processed in case the target surface parent is destroyed during the drop
  1078. // action.
  1079. TEST_F(PointerTest,
  1080. DragDropAndPointerEnterLeaveEvents_NoEnterOnParentSurfaceDestroy) {
  1081. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  1082. MockPointerDelegate pointer_delegate;
  1083. std::unique_ptr<Pointer> pointer(new Pointer(&pointer_delegate, &seat));
  1084. TestDataSourceDelegate data_source_delegate;
  1085. DataSource source(&data_source_delegate);
  1086. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  1087. auto* surface = shell_surface->surface_for_testing();
  1088. auto closure = base::BindOnce([](std::unique_ptr<ShellSurface> shell_surface,
  1089. ui::mojom::DragOperation& output_drag_op) {},
  1090. std::move(shell_surface));
  1091. PointerDragDropObserver drag_drop_observer(std::move(closure));
  1092. auto* wm_helper = WMHelper::GetInstance();
  1093. wm_helper->AddDragDropObserver(&drag_drop_observer);
  1094. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  1095. EXPECT_CALL(pointer_delegate, CanAcceptPointerEventsForSurface(testing::_))
  1096. .WillRepeatedly(testing::Return(true));
  1097. EXPECT_CALL(pointer_delegate, OnPointerFrame()).Times(AnyNumber());
  1098. EXPECT_CALL(pointer_delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  1099. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  1100. auto* drag_drop_controller = static_cast<ash::DragDropController*>(
  1101. aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  1102. ASSERT_TRUE(drag_drop_controller);
  1103. generator.PressLeftButton();
  1104. seat.StartDrag(&source, surface, /*icon=*/nullptr,
  1105. ui::mojom::DragEventSource::kMouse);
  1106. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  1107. // As soon as the runloop gets triggered, emit a mouse release event.
  1108. drag_drop_controller->SetLoopClosureForTesting(
  1109. base::BindLambdaForTesting([&]() {
  1110. EXPECT_CALL(pointer_delegate, OnPointerEnter(_, _, _)).Times(1);
  1111. generator.ReleaseLeftButton();
  1112. }),
  1113. base::DoNothing());
  1114. // OnPointerLeave() gets called twice:
  1115. // 1/ when the drag starts;
  1116. // 2/ when the dragging window gets destroyed.
  1117. EXPECT_CALL(pointer_delegate, OnPointerLeave(_)).Times(2);
  1118. base::RunLoop().RunUntilIdle();
  1119. wm_helper->RemoveDragDropObserver(&drag_drop_observer);
  1120. EXPECT_CALL(pointer_delegate, OnPointerDestroying(pointer.get()));
  1121. pointer.reset();
  1122. }
  1123. #endif
  1124. TEST_F(PointerTest, OnPointerRelativeMotion) {
  1125. auto surface = std::make_unique<Surface>();
  1126. auto shell_surface = std::make_unique<ShellSurface>(surface.get());
  1127. gfx::Size buffer_size(10, 10);
  1128. std::unique_ptr<Buffer> buffer(
  1129. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  1130. surface->Attach(buffer.get());
  1131. surface->Commit();
  1132. MockPointerDelegate delegate;
  1133. MockRelativePointerDelegate relative_delegate;
  1134. Seat seat;
  1135. auto pointer = std::make_unique<Pointer>(&delegate, &seat);
  1136. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  1137. pointer->RegisterRelativePointerDelegate(&relative_delegate);
  1138. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  1139. .WillRepeatedly(testing::Return(true));
  1140. EXPECT_CALL(delegate, OnPointerFrame()).Times(9);
  1141. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  1142. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  1143. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  1144. EXPECT_CALL(
  1145. relative_delegate,
  1146. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1), testing::_));
  1147. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() +
  1148. gfx::Vector2d(1, 1));
  1149. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(2, 2)));
  1150. EXPECT_CALL(
  1151. relative_delegate,
  1152. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1), testing::_));
  1153. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() +
  1154. gfx::Vector2d(2, 2));
  1155. auto sub_surface = std::make_unique<Surface>();
  1156. auto sub = std::make_unique<SubSurface>(sub_surface.get(), surface.get());
  1157. surface->SetSubSurfacePosition(sub_surface.get(), gfx::PointF(5, 5));
  1158. gfx::Size sub_buffer_size(5, 5);
  1159. auto sub_buffer = std::make_unique<Buffer>(
  1160. exo_test_helper()->CreateGpuMemoryBuffer(sub_buffer_size));
  1161. sub_surface->Attach(sub_buffer.get());
  1162. sub_surface->Commit();
  1163. surface->Commit();
  1164. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(sub_surface.get()))
  1165. .WillRepeatedly(testing::Return(true));
  1166. EXPECT_CALL(delegate, OnPointerLeave(surface.get()));
  1167. EXPECT_CALL(delegate, OnPointerEnter(sub_surface.get(), gfx::PointF(), 0));
  1168. // OnPointerMotion will not be called, because the pointer location is already
  1169. // sent with OnPointerEnter, but we should still receive
  1170. // OnPointerRelativeMotion.
  1171. EXPECT_CALL(
  1172. relative_delegate,
  1173. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(3, 3), testing::_));
  1174. generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin());
  1175. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  1176. EXPECT_CALL(
  1177. relative_delegate,
  1178. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1), testing::_));
  1179. generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin() +
  1180. gfx::Vector2d(1, 1));
  1181. const gfx::Point child_surface_origin =
  1182. sub_surface->window()->GetBoundsInScreen().origin() +
  1183. gfx::Vector2d(10, 10);
  1184. auto child_surface = std::make_unique<Surface>();
  1185. auto child_shell_surface = std::make_unique<ShellSurface>(
  1186. child_surface.get(), child_surface_origin, /*can_minimize=*/false,
  1187. ash::desks_util::GetActiveDeskContainerId());
  1188. child_shell_surface->DisableMovement();
  1189. child_shell_surface->SetParent(shell_surface.get());
  1190. gfx::Size child_buffer_size(15, 15);
  1191. auto child_buffer = std::make_unique<Buffer>(
  1192. exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size));
  1193. child_surface->Attach(child_buffer.get());
  1194. child_surface->Commit();
  1195. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(child_surface.get()))
  1196. .WillRepeatedly(testing::Return(true));
  1197. EXPECT_CALL(delegate, OnPointerLeave(sub_surface.get()));
  1198. EXPECT_CALL(delegate, OnPointerEnter(child_surface.get(), gfx::PointF(), 0));
  1199. // OnPointerMotion will not be called, because the pointer location is already
  1200. // sent with OnPointerEnter, but we should still receive
  1201. // OnPointerRelativeMotion.
  1202. EXPECT_CALL(
  1203. relative_delegate,
  1204. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(9, 9), testing::_));
  1205. generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin());
  1206. EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(10, 10)));
  1207. EXPECT_CALL(
  1208. relative_delegate,
  1209. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(10, 10), testing::_));
  1210. generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin() +
  1211. gfx::Vector2d(10, 10));
  1212. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  1213. EXPECT_CALL(relative_delegate, OnPointerDestroying(pointer.get()));
  1214. pointer.reset();
  1215. }
  1216. // TODO(b/161755250): the ifdef is only necessary because of the feature
  1217. // flag. This code should work fine on non-cros.
  1218. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1219. class PointerOrdinalMotionTest : public PointerTest {
  1220. public:
  1221. PointerOrdinalMotionTest() {
  1222. scoped_feature_list_.InitAndEnableFeature(
  1223. chromeos::features::kExoOrdinalMotion);
  1224. }
  1225. private:
  1226. base::test::ScopedFeatureList scoped_feature_list_;
  1227. };
  1228. TEST_F(PointerOrdinalMotionTest, OrdinalMotionOverridesRelativeMotion) {
  1229. auto surface = std::make_unique<Surface>();
  1230. auto shell_surface = std::make_unique<ShellSurface>(surface.get());
  1231. gfx::Size buffer_size(10, 10);
  1232. std::unique_ptr<Buffer> buffer(
  1233. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  1234. surface->Attach(buffer.get());
  1235. surface->Commit();
  1236. // Set up the pointer and move it to the origin.
  1237. testing::NiceMock<MockPointerDelegate> delegate;
  1238. Seat seat;
  1239. auto pointer = std::make_unique<Pointer>(&delegate, &seat);
  1240. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  1241. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  1242. .WillRepeatedly(testing::Return(true));
  1243. gfx::Point origin = surface->window()->GetBoundsInScreen().origin();
  1244. generator.MoveMouseTo(origin);
  1245. // Start sending relative motion events.
  1246. testing::StrictMock<MockRelativePointerDelegate> relative_delegate;
  1247. pointer->RegisterRelativePointerDelegate(&relative_delegate);
  1248. // By default, ordinal and relative are the same.
  1249. gfx::Point new_location = origin + gfx::Vector2d(1, 1);
  1250. ui::MouseEvent ev1(ui::ET_MOUSE_MOVED, new_location, new_location,
  1251. ui::EventTimeForNow(), generator.flags(), 0);
  1252. EXPECT_CALL(relative_delegate,
  1253. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1),
  1254. gfx::Vector2dF(1, 1)));
  1255. generator.Dispatch(&ev1);
  1256. // When set, ordinal overrides the relative motion.
  1257. new_location = new_location + gfx::Vector2d(1, 1);
  1258. ui::MouseEvent ev2(ui::ET_MOUSE_MOVED, new_location, new_location,
  1259. ui::EventTimeForNow(), generator.flags(), 0);
  1260. ui::MouseEvent::DispatcherApi(&ev2).set_movement(gfx::Vector2dF(99, 99));
  1261. EXPECT_CALL(relative_delegate,
  1262. OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1),
  1263. gfx::Vector2dF(99, 99)));
  1264. generator.Dispatch(&ev2);
  1265. pointer->UnregisterRelativePointerDelegate(&relative_delegate);
  1266. }
  1267. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  1268. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1269. TEST_F(PointerConstraintTest, ConstrainPointer) {
  1270. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1271. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1272. EXPECT_CALL(delegate_, OnPointerFrame());
  1273. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1274. EXPECT_CALL(delegate_, OnPointerMotion(testing::_, testing::_)).Times(0);
  1275. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin() +
  1276. gfx::Vector2d(-1, -1));
  1277. auto child_shell_surface = test::ShellSurfaceBuilder({15, 15})
  1278. .SetParent(shell_surface_.get())
  1279. .SetDisableMovement()
  1280. .SetCanMinimize(false)
  1281. .BuildShellSurface();
  1282. Surface* child_surface = child_shell_surface->surface_for_testing();
  1283. EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(child_surface))
  1284. .WillRepeatedly(testing::Return(true));
  1285. generator_->MoveMouseTo(
  1286. child_surface->window()->GetBoundsInScreen().origin());
  1287. EXPECT_CALL(delegate_, OnPointerLeave(surface_));
  1288. EXPECT_CALL(delegate_, OnPointerEnter(child_surface, gfx::PointF(), 0));
  1289. EXPECT_CALL(delegate_, OnPointerFrame());
  1290. // Moving the cursor to a different surface should change the focus when
  1291. // the pointer is unconstrained.
  1292. pointer_->UnconstrainPointerByUserAction();
  1293. generator_->MoveMouseTo(
  1294. child_surface->window()->GetBoundsInScreen().origin());
  1295. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1296. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1297. pointer_.reset();
  1298. }
  1299. #endif
  1300. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1301. TEST_F(PointerConstraintTest, CanOnlyConstrainPermittedWindows) {
  1302. std::unique_ptr<ShellSurface> shell_surface =
  1303. test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  1304. EXPECT_CALL(constraint_delegate_, GetConstrainedSurface())
  1305. .WillRepeatedly(testing::Return(shell_surface->surface_for_testing()));
  1306. // Called once when ConstrainPointer is denied, and again when the delegate
  1307. // is destroyed.
  1308. EXPECT_CALL(constraint_delegate_, OnDefunct()).Times(2);
  1309. EXPECT_FALSE(pointer_->ConstrainPointer(&constraint_delegate_));
  1310. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1311. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1312. pointer_.reset();
  1313. }
  1314. #endif
  1315. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1316. TEST_F(PointerConstraintTest, OneConstraintPerSurface) {
  1317. ON_CALL(constraint_delegate_, IsPersistent())
  1318. .WillByDefault(testing::Return(false));
  1319. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1320. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1321. EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  1322. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1323. // Add a second constraint for the same surface, it should fail.
  1324. MockPointerConstraintDelegate second_constraint;
  1325. EXPECT_CALL(second_constraint, GetConstrainedSurface())
  1326. .WillRepeatedly(testing::Return(surface_));
  1327. ON_CALL(second_constraint, IsPersistent())
  1328. .WillByDefault(testing::Return(false));
  1329. EXPECT_CALL(second_constraint, OnAlreadyConstrained());
  1330. EXPECT_CALL(second_constraint, OnDefunct());
  1331. EXPECT_FALSE(pointer_->ConstrainPointer(&second_constraint));
  1332. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1333. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1334. pointer_.reset();
  1335. }
  1336. #endif
  1337. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1338. TEST_F(PointerConstraintTest, OneShotConstraintActivatedOnFirstFocus) {
  1339. auto second_shell_surface = BuildShellSurfaceWhichPermitsPointerLock();
  1340. Surface* second_surface = second_shell_surface->surface_for_testing();
  1341. EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(second_surface))
  1342. .WillRepeatedly(testing::Return(true));
  1343. focus_client_->FocusWindow(second_surface->window());
  1344. // Assert: Can no longer activate the constraint on the first surface.
  1345. EXPECT_FALSE(pointer_->ConstrainPointer(&constraint_delegate_));
  1346. EXPECT_EQ(constraint_delegate_.activated_count, 0);
  1347. // Assert: Constraint is activated when first surface gains focus.
  1348. focus_client_->FocusWindow(surface_->window());
  1349. EXPECT_EQ(constraint_delegate_.activated_count, 1);
  1350. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1351. EXPECT_CALL(delegate_, OnPointerFrame());
  1352. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1353. // Teardown
  1354. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1355. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1356. pointer_.reset();
  1357. }
  1358. #endif
  1359. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1360. TEST_F(PointerConstraintTest, UnconstrainPointerWhenSurfaceIsDestroyed) {
  1361. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1362. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1363. EXPECT_CALL(delegate_, OnPointerFrame());
  1364. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1365. // Constraint should be broken if surface is destroyed.
  1366. EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  1367. EXPECT_CALL(delegate_, OnPointerLeave(surface_));
  1368. EXPECT_CALL(delegate_, OnPointerFrame());
  1369. shell_surface_.reset();
  1370. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1371. pointer_.reset();
  1372. }
  1373. #endif
  1374. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1375. TEST_F(PointerConstraintTest, UnconstrainPointerWhenWindowLosesFocus) {
  1376. ON_CALL(constraint_delegate_, IsPersistent())
  1377. .WillByDefault(testing::Return(false));
  1378. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1379. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1380. EXPECT_CALL(delegate_, OnPointerFrame());
  1381. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1382. EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  1383. EXPECT_CALL(constraint_delegate_, OnConstraintActivated()).Times(0);
  1384. focus_client_->FocusWindow(nullptr);
  1385. focus_client_->FocusWindow(surface_->window());
  1386. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1387. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1388. pointer_.reset();
  1389. }
  1390. #endif
  1391. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1392. TEST_F(PointerConstraintTest, PersistentConstraintActivatedOnRefocus) {
  1393. ON_CALL(constraint_delegate_, IsPersistent())
  1394. .WillByDefault(testing::Return(true));
  1395. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1396. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1397. EXPECT_CALL(delegate_, OnPointerFrame());
  1398. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1399. EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  1400. focus_client_->FocusWindow(nullptr);
  1401. EXPECT_CALL(constraint_delegate_, OnConstraintActivated());
  1402. focus_client_->FocusWindow(surface_->window());
  1403. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1404. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1405. pointer_.reset();
  1406. }
  1407. #endif
  1408. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1409. TEST_F(PointerConstraintTest, MultipleSurfacesCanBeConstrained) {
  1410. // Arrange: First surface + persistent constraint
  1411. ON_CALL(constraint_delegate_, IsPersistent())
  1412. .WillByDefault(testing::Return(true));
  1413. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1414. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1415. EXPECT_CALL(delegate_, OnPointerFrame());
  1416. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1417. EXPECT_EQ(constraint_delegate_.activated_count, 1);
  1418. // Arrange: Second surface + persistent constraint
  1419. auto second_shell_surface = BuildShellSurfaceWhichPermitsPointerLock();
  1420. Surface* second_surface = second_shell_surface->surface_for_testing();
  1421. focus_client_->FocusWindow(second_surface->window());
  1422. EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(second_surface))
  1423. .WillRepeatedly(testing::Return(true));
  1424. testing::NiceMock<MockPointerConstraintDelegate> second_constraint;
  1425. EXPECT_CALL(second_constraint, GetConstrainedSurface())
  1426. .WillRepeatedly(testing::Return(second_surface));
  1427. ON_CALL(second_constraint, IsPersistent())
  1428. .WillByDefault(testing::Return(true));
  1429. EXPECT_TRUE(pointer_->ConstrainPointer(&second_constraint));
  1430. EXPECT_EQ(constraint_delegate_.activated_count, 1);
  1431. EXPECT_EQ(second_constraint.activated_count, 1);
  1432. // Act: Toggle focus, first surface's constraint should activate.
  1433. focus_client_->FocusWindow(surface_->window());
  1434. EXPECT_EQ(constraint_delegate_.activated_count, 2);
  1435. EXPECT_EQ(second_constraint.activated_count, 1);
  1436. // Act: Toggle focus, second surface's constraint should activate.
  1437. focus_client_->FocusWindow(second_surface->window());
  1438. EXPECT_EQ(constraint_delegate_.activated_count, 2);
  1439. EXPECT_EQ(second_constraint.activated_count, 2);
  1440. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1441. pointer_->OnPointerConstraintDelegateDestroying(&second_constraint);
  1442. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1443. pointer_.reset();
  1444. }
  1445. #endif
  1446. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1447. TEST_F(PointerConstraintTest, UserActionPreventsConstraint) {
  1448. ON_CALL(constraint_delegate_, IsPersistent())
  1449. .WillByDefault(testing::Return(false));
  1450. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1451. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1452. EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  1453. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1454. EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  1455. pointer_->UnconstrainPointerByUserAction();
  1456. // New constraints are no longer permitted.
  1457. MockPointerConstraintDelegate second_constraint;
  1458. EXPECT_CALL(second_constraint, GetConstrainedSurface())
  1459. .WillRepeatedly(testing::Return(surface_));
  1460. ON_CALL(second_constraint, IsPersistent())
  1461. .WillByDefault(testing::Return(false));
  1462. EXPECT_FALSE(pointer_->ConstrainPointer(&second_constraint));
  1463. EXPECT_EQ(second_constraint.activated_count, 0);
  1464. // A click event will activate the pending constraint.
  1465. generator_->ClickLeftButton();
  1466. EXPECT_EQ(second_constraint.activated_count, 1);
  1467. pointer_->OnPointerConstraintDelegateDestroying(&second_constraint);
  1468. // New constraints are now permitted too.
  1469. MockPointerConstraintDelegate third_constraint;
  1470. EXPECT_CALL(third_constraint, GetConstrainedSurface())
  1471. .WillRepeatedly(testing::Return(surface_));
  1472. ON_CALL(third_constraint, IsPersistent())
  1473. .WillByDefault(testing::Return(false));
  1474. EXPECT_TRUE(pointer_->ConstrainPointer(&third_constraint));
  1475. pointer_->OnPointerConstraintDelegateDestroying(&third_constraint);
  1476. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1477. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1478. pointer_.reset();
  1479. }
  1480. #endif
  1481. #if BUILDFLAG(IS_CHROMEOS_ASH)
  1482. TEST_F(PointerConstraintTest, UserCanBreakAndActivatePersistentConstraint) {
  1483. ON_CALL(constraint_delegate_, IsPersistent())
  1484. .WillByDefault(testing::Return(true));
  1485. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  1486. EXPECT_EQ(constraint_delegate_.activated_count, 1);
  1487. EXPECT_EQ(constraint_delegate_.broken_count, 0);
  1488. EXPECT_CALL(delegate_, OnPointerEnter(surface_, gfx::PointF(), 0));
  1489. EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  1490. generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());
  1491. EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  1492. pointer_->UnconstrainPointerByUserAction();
  1493. EXPECT_EQ(constraint_delegate_.activated_count, 1);
  1494. EXPECT_EQ(constraint_delegate_.broken_count, 1);
  1495. // Click events re-enable the constraint.
  1496. generator_->ClickLeftButton();
  1497. EXPECT_EQ(constraint_delegate_.activated_count, 2);
  1498. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  1499. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1500. pointer_.reset();
  1501. }
  1502. TEST_F(PointerConstraintTest, DefaultSecrityDeletegate) {
  1503. auto default_security_delegate =
  1504. SecurityDelegate::GetDefaultSecurityDelegate();
  1505. auto shell_surface = test::ShellSurfaceBuilder({10, 10})
  1506. .SetSecurityDelegate(default_security_delegate.get())
  1507. .BuildShellSurface();
  1508. auto* surface = shell_surface->surface_for_testing();
  1509. focus_client_->FocusWindow(surface->window());
  1510. MockPointerConstraintDelegate constraint_delegate;
  1511. EXPECT_CALL(constraint_delegate, GetConstrainedSurface())
  1512. .WillRepeatedly(testing::Return(surface));
  1513. EXPECT_CALL(constraint_delegate, OnDefunct()).Times(1);
  1514. EXPECT_FALSE(pointer_->ConstrainPointer(&constraint_delegate));
  1515. ::testing::Mock::VerifyAndClearExpectations(&constraint_delegate);
  1516. shell_surface->GetWidget()->GetNativeWindow()->SetProperty(
  1517. aura::client::kAppType, static_cast<int>(ash::AppType::LACROS));
  1518. EXPECT_CALL(constraint_delegate, GetConstrainedSurface())
  1519. .WillRepeatedly(testing::Return(surface));
  1520. EXPECT_CALL(constraint_delegate, OnDefunct()).Times(0);
  1521. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate));
  1522. ::testing::Mock::VerifyAndClearExpectations(&constraint_delegate);
  1523. EXPECT_CALL(constraint_delegate, GetConstrainedSurface())
  1524. .WillRepeatedly(testing::Return(surface));
  1525. shell_surface->GetWidget()->GetNativeWindow()->SetProperty(
  1526. aura::client::kAppType, static_cast<int>(ash::AppType::ARC_APP));
  1527. EXPECT_CALL(constraint_delegate, OnDefunct()).Times(0);
  1528. EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate));
  1529. ::testing::Mock::VerifyAndClearExpectations(&constraint_delegate);
  1530. pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate);
  1531. EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  1532. pointer_.reset();
  1533. }
  1534. #endif
  1535. TEST_F(PointerTest, PointerStylus) {
  1536. std::unique_ptr<Surface> surface(new Surface);
  1537. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  1538. gfx::Size buffer_size(10, 10);
  1539. std::unique_ptr<Buffer> buffer(
  1540. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  1541. surface->Attach(buffer.get());
  1542. surface->Commit();
  1543. MockPointerDelegate delegate;
  1544. MockPointerStylusDelegate stylus_delegate;
  1545. Seat seat;
  1546. std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
  1547. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  1548. pointer->SetStylusDelegate(&stylus_delegate);
  1549. EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
  1550. .WillRepeatedly(testing::Return(true));
  1551. {
  1552. testing::InSequence sequence;
  1553. EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
  1554. EXPECT_CALL(delegate, OnPointerFrame());
  1555. EXPECT_CALL(stylus_delegate,
  1556. OnPointerToolChange(ui::EventPointerType::kMouse));
  1557. EXPECT_CALL(delegate, OnPointerFrame());
  1558. }
  1559. generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());
  1560. EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  1561. EXPECT_CALL(stylus_delegate, OnPointerDestroying(pointer.get()));
  1562. pointer.reset();
  1563. }
  1564. } // namespace
  1565. } // namespace exo