123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/exo/touch.h"
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/shell.h"
- #include "ash/wm/window_positioner.h"
- #include "ash/wm/window_positioning_utils.h"
- #include "components/exo/buffer.h"
- #include "components/exo/data_source.h"
- #include "components/exo/data_source_delegate.h"
- #include "components/exo/seat.h"
- #include "components/exo/shell_surface.h"
- #include "components/exo/surface.h"
- #include "components/exo/test/exo_test_base.h"
- #include "components/exo/test/exo_test_data_exchange_delegate.h"
- #include "components/exo/test/exo_test_helper.h"
- #include "components/exo/test/shell_surface_builder.h"
- #include "components/exo/touch_delegate.h"
- #include "components/exo/touch_stylus_delegate.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
- #include "ui/events/base_event_utils.h"
- #include "ui/events/test/event_generator.h"
- #include "ui/views/widget/widget.h"
- namespace exo {
- namespace {
- using TouchTest = test::ExoTestBase;
- class MockTouchDelegate : public TouchDelegate {
- public:
- MockTouchDelegate() {}
- // Overridden from TouchDelegate:
- MOCK_METHOD1(OnTouchDestroying, void(Touch*));
- MOCK_CONST_METHOD1(CanAcceptTouchEventsForSurface, bool(Surface*));
- MOCK_METHOD4(OnTouchDown,
- void(Surface*, base::TimeTicks, int, const gfx::PointF&));
- MOCK_METHOD2(OnTouchUp, void(base::TimeTicks, int));
- MOCK_METHOD3(OnTouchMotion, void(base::TimeTicks, int, const gfx::PointF&));
- MOCK_METHOD3(OnTouchShape, void(int, float, float));
- MOCK_METHOD0(OnTouchFrame, void());
- MOCK_METHOD0(OnTouchCancel, void());
- };
- class MockTouchStylusDelegate : public TouchStylusDelegate {
- public:
- MockTouchStylusDelegate() {}
- // Overridden from TouchStylusDelegate:
- MOCK_METHOD1(OnTouchDestroying, void(Touch*));
- MOCK_METHOD2(OnTouchTool, void(int, ui::EventPointerType));
- MOCK_METHOD3(OnTouchForce, void(base::TimeTicks, int, float));
- MOCK_METHOD3(OnTouchTilt, void(base::TimeTicks, int, const gfx::Vector2dF&));
- };
- class TestDataSourceDelegate : public DataSourceDelegate {
- public:
- TestDataSourceDelegate() {}
- TestDataSourceDelegate(const TestDataSourceDelegate&) = delete;
- TestDataSourceDelegate& operator=(const TestDataSourceDelegate&) = delete;
- // Overridden from DataSourceDelegate:
- void OnDataSourceDestroying(DataSource* device) override {}
- void OnTarget(const absl::optional<std::string>& mime_type) override {}
- void OnSend(const std::string& mime_type, base::ScopedFD fd) override {}
- void OnCancelled() override {}
- void OnDndDropPerformed() override {}
- void OnDndFinished() override {}
- void OnAction(DndAction dnd_action) override {}
- bool CanAcceptDataEventsForSurface(Surface* surface) const override {
- return true;
- }
- };
- TEST_F(TouchTest, OnTouchDown) {
- MockTouchDelegate delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- auto bottom_shell_surface =
- test::ShellSurfaceBuilder({10, 10}).SetCentered().BuildShellSurface();
- auto top_shell_surface =
- test::ShellSurfaceBuilder({8, 8}).SetCentered().BuildShellSurface();
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate,
- CanAcceptTouchEventsForSurface(top_shell_surface->root_surface()))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate, OnTouchDown(top_shell_surface->root_surface(),
- testing::_, 1, gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.set_current_screen_location(
- GetOriginOfShellSurface(top_shell_surface.get()));
- generator.PressTouchId(1);
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(
- bottom_shell_surface->root_surface()))
- .WillRepeatedly(testing::Return(true));
- // Second touch point should be relative to the focus surface.
- EXPECT_CALL(delegate, OnTouchDown(top_shell_surface->root_surface(),
- testing::_, 2, gfx::PointF(-1, -1)));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.set_current_screen_location(
- GetOriginOfShellSurface(bottom_shell_surface.get()));
- generator.PressTouchId(2);
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchUp) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()))
- .Times(2);
- EXPECT_CALL(delegate, OnTouchFrame()).Times(2);
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressTouchId(1);
- generator.PressTouchId(2);
- EXPECT_CALL(delegate, OnTouchUp(testing::_, 1));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.ReleaseTouchId(1);
- EXPECT_CALL(delegate, OnTouchUp(testing::_, 2));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.ReleaseTouchId(2);
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchMotion) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()));
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(5, 5)));
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame()).Times(3);
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressMoveAndReleaseTouchBy(5, 5);
- // Check if touch point motion outside focus surface is reported properly to
- // the focus surface.
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()));
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(100, 100)));
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame()).Times(3);
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressMoveAndReleaseTouchBy(100, 100);
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchShape) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
- gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchShape(testing::_, 20, 10));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(5, 5)));
- EXPECT_CALL(delegate, OnTouchShape(testing::_, 20, 10));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(10, 10)));
- EXPECT_CALL(delegate, OnTouchShape(testing::_, 20, 20));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame());
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.SetTouchRadius(10, 5);
- generator.PressTouch();
- generator.MoveTouchBy(5, 5);
- generator.SetTouchRadius(10, 0); // Minor not supported
- generator.MoveTouchBy(5, 5);
- generator.ReleaseTouch();
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchCancel) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()))
- .Times(2);
- EXPECT_CALL(delegate, OnTouchFrame()).Times(2);
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressTouchId(1);
- generator.PressTouchId(2);
- // One touch point being canceled is enough for OnTouchCancel to be called.
- EXPECT_CALL(delegate, OnTouchCancel());
- EXPECT_CALL(delegate, OnTouchFrame());
- ui::TouchEvent cancel_event(
- ui::ET_TOUCH_CANCELLED, gfx::Point(), ui::EventTimeForNow(),
- ui::PointerDetails(ui::EventPointerType::kTouch, 1));
- generator.Dispatch(&cancel_event);
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchCancelWhenSurfaceDestroying) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- auto touch = std::make_unique<Touch>(&delegate, &seat);
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, 1, gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressTouchId(1);
- // Since there is an active touch pointer on the surface, destroying the
- // surface should cancel touches.
- EXPECT_CALL(delegate, OnTouchCancel());
- EXPECT_CALL(delegate, OnTouchFrame());
- test::ShellSurfaceBuilder::DestroyRootSurface(shell_surface.get());
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchCancelNotTriggeredAfterTouchReleased) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- auto touch = std::make_unique<Touch>(&delegate, &seat);
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, 1, gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressTouchId(1);
- EXPECT_CALL(delegate, OnTouchUp(testing::_, 1));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.ReleaseTouchId(1);
- // Since the surface no longer has any active touch pointers, destroying the
- // surface should not cancel any touches.
- EXPECT_CALL(delegate, OnTouchCancel()).Times(0);
- test::ShellSurfaceBuilder::DestroyRootSurface(shell_surface.get());
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, IgnoreTouchEventDuringModal) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10})
- .SetCentered()
- .SetCanMinimize(false)
- .BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- auto modal_shell_surface = test::ShellSurfaceBuilder({5, 5})
- .SetCentered()
- .SetUseSystemModalContainer()
- .SetCanMinimize(false)
- .BuildShellSurface();
- auto* modal_root_surface = modal_shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- // Make the window modal.
- EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen());
- modal_shell_surface->SetSystemModal(true);
- EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(modal_root_surface))
- .WillRepeatedly(testing::Return(true));
- // Check if touch events on modal window are registered.
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(modal_root_surface, testing::_,
- testing::_, gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(1, 1)));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame());
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(modal_shell_surface.get()));
- generator.PressMoveAndReleaseTouchBy(1, 1);
- // Check if touch events on non-modal window are ignored.
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
- gfx::PointF()))
- .Times(0);
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(1, 1)))
- .Times(0);
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_)).Times(0);
- EXPECT_CALL(delegate, OnTouchFrame()).Times(0);
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressMoveAndReleaseTouchBy(1, 1);
- // Make the window non-modal.
- modal_shell_surface->SetSystemModal(false);
- EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen());
- // Check if touch events on non-modal window are registered.
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
- gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate,
- OnTouchMotion(testing::_, testing::_, gfx::PointF(1, 1)));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame());
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.PressMoveAndReleaseTouchBy(1, 1);
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchTool) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- MockTouchStylusDelegate stylus_delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- touch->SetStylusDelegate(&stylus_delegate);
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- // Expect tool change to happen before frame of down event.
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
- gfx::PointF()));
- EXPECT_CALL(stylus_delegate, OnTouchTool(0, ui::EventPointerType::kPen));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame());
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.SetTouchPointerType(ui::EventPointerType::kPen);
- generator.PressTouch();
- generator.ReleaseTouch();
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchForce) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- MockTouchStylusDelegate stylus_delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- touch->SetStylusDelegate(&stylus_delegate);
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- // Expect tool change to happen before frame of down event.
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
- gfx::PointF()));
- EXPECT_CALL(stylus_delegate, OnTouchTool(0, ui::EventPointerType::kPen));
- EXPECT_CALL(stylus_delegate, OnTouchForce(testing::_, 0, 1.0));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame());
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.SetTouchPointerType(ui::EventPointerType::kPen);
- generator.SetTouchForce(1.0);
- generator.PressTouch();
- generator.ReleaseTouch();
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, OnTouchTilt) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- MockTouchDelegate delegate;
- MockTouchStylusDelegate stylus_delegate;
- Seat seat;
- std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- touch->SetStylusDelegate(&stylus_delegate);
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- // Expect tool change to happen before frame of down event.
- {
- testing::InSequence sequence;
- EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
- gfx::PointF()));
- EXPECT_CALL(stylus_delegate, OnTouchTool(0, ui::EventPointerType::kPen));
- EXPECT_CALL(stylus_delegate,
- OnTouchTilt(testing::_, 0, gfx::Vector2dF(1.0, 2.0)));
- EXPECT_CALL(delegate, OnTouchFrame());
- EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
- EXPECT_CALL(delegate, OnTouchFrame());
- }
- generator.set_current_screen_location(
- GetOriginOfShellSurface(shell_surface.get()));
- generator.SetTouchPointerType(ui::EventPointerType::kPen);
- generator.SetTouchTilt(1.0, 2.0);
- generator.PressTouch();
- generator.ReleaseTouch();
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, DragDropAbort) {
- Seat seat(std::make_unique<TestDataExchangeDelegate>());
- MockTouchDelegate touch_delegate;
- std::unique_ptr<Touch> touch(new Touch(&touch_delegate, &seat));
- TestDataSourceDelegate data_source_delegate;
- DataSource source(&data_source_delegate);
- Surface origin, icon;
- // Make origin into a real window so the touch can click it
- ShellSurface shell_surface(&origin);
- Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)));
- origin.Attach(&buffer);
- origin.Commit();
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- EXPECT_CALL(touch_delegate, CanAcceptTouchEventsForSurface(&origin))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(touch_delegate, OnTouchFrame()).Times(2);
- generator.MoveTouch(origin.window()->GetBoundsInScreen().origin());
- seat.StartDrag(&source, &origin, &icon, ui::mojom::DragEventSource::kMouse);
- EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
- EXPECT_CALL(touch_delegate, OnTouchDown).Times(1);
- EXPECT_CALL(touch_delegate, OnTouchUp).Times(1);
- EXPECT_CALL(touch_delegate, OnTouchShape).Times(1);
- generator.PressTouch();
- EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
- generator.ReleaseTouch();
- EXPECT_FALSE(seat.get_drag_drop_operation_for_testing());
- EXPECT_CALL(touch_delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, TouchMultiple2Surfaces) {
- auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- auto* root_surface = shell_surface->root_surface();
- auto child_shell_surface = test::ShellSurfaceBuilder({15, 15})
- .SetParent(shell_surface.get())
- .SetCanMinimize(false)
- .SetDisableMovement()
- .BuildShellSurface();
- auto* child_surface = child_shell_surface->root_surface();
- MockTouchDelegate delegate;
- Seat seat;
- auto touch = std::make_unique<Touch>(&delegate, &seat);
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- // Touch down on the two surfaces.
- EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(root_surface, testing::_, 1, gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- const gfx::Point origin = GetOriginOfShellSurface(shell_surface.get());
- generator.set_current_screen_location(origin);
- generator.PressTouchId(1);
- EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(child_surface))
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(delegate,
- OnTouchDown(child_surface, testing::_, 2, gfx::PointF()));
- EXPECT_CALL(delegate, OnTouchFrame());
- const gfx::Point child_origin =
- GetOriginOfShellSurface(child_shell_surface.get());
- generator.set_current_screen_location(child_origin);
- generator.PressTouchId(2);
- // Move the two touch pointers.
- for (int i = 1; i <= 10; i++) {
- EXPECT_CALL(delegate, OnTouchMotion(testing::_, 1, gfx::PointF(i, i)));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.MoveTouchId(origin + gfx::Vector2d(i, i), 1);
- EXPECT_CALL(delegate, OnTouchMotion(testing::_, 2, gfx::PointF(i, i)));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.MoveTouchId(child_origin + gfx::Vector2d(i, i), 2);
- }
- // Release the two touch pointers.
- EXPECT_CALL(delegate, OnTouchUp(testing::_, 2));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.ReleaseTouchId(2);
- EXPECT_CALL(delegate, OnTouchUp(testing::_, 1));
- EXPECT_CALL(delegate, OnTouchFrame());
- generator.ReleaseTouchId(1);
- EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
- touch.reset();
- }
- TEST_F(TouchTest, IgnoresHandledEvents) {
- // A very dumb handler that simply marks all events as handled. This is needed
- // allows us to mark a mouse event as handled as it gets processed by the
- // event processor.
- class SetHandledHandler : public ui::EventHandler {
- void OnTouchEvent(ui::TouchEvent* event) override { event->SetHandled(); }
- };
- SetHandledHandler handler;
- ash::Shell::Get()->AddPreTargetHandler(&handler);
- Seat seat(std::make_unique<TestDataExchangeDelegate>());
- testing::NiceMock<MockTouchDelegate> touch_delegate;
- std::unique_ptr<Touch> touch(new Touch(&touch_delegate, &seat));
- // Make origin into a real window so the touch can click it
- std::unique_ptr<ShellSurface> shell_surface =
- test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
- ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
- // The SetHandlerHandler should have marked the event as processed. Therefore
- // the event should simply be ignored.
- EXPECT_CALL(touch_delegate, OnTouchFrame()).Times(0);
- generator.GestureTapAt(shell_surface->surface_for_testing()
- ->window()
- ->GetBoundsInScreen()
- .CenterPoint());
- ash::Shell::Get()->RemovePreTargetHandler(&handler);
- }
- } // namespace
- } // namespace exo
|