123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- // 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 "ui/events/scoped_target_handler.h"
- #include <memory>
- #include <utility>
- #include "base/memory/ptr_util.h"
- #include "base/memory/raw_ptr.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "ui/events/event_handler.h"
- #include "ui/events/event_target.h"
- #include "ui/events/event_target_iterator.h"
- #include "ui/events/event_utils.h"
- namespace ui {
- namespace {
- class TestEventTargetIterator : public EventTargetIterator {
- public:
- TestEventTargetIterator() {}
- TestEventTargetIterator(const TestEventTargetIterator&) = delete;
- TestEventTargetIterator& operator=(const TestEventTargetIterator&) = delete;
- // EventTargetIterator:
- EventTarget* GetNextTarget() override { return nullptr; }
- };
- // An EventTarget that holds ownership of its target and delegate EventHandlers.
- class TestEventTarget : public EventTarget {
- public:
- TestEventTarget() {}
- TestEventTarget(const TestEventTarget&) = delete;
- TestEventTarget& operator=(const TestEventTarget&) = delete;
- ~TestEventTarget() override {}
- void SetHandler(std::unique_ptr<EventHandler> target_handler,
- std::unique_ptr<EventHandler> delegate) {
- target_handler_ = std::move(target_handler);
- delegate_ = std::move(delegate);
- }
- // EventTarget:
- void DispatchEvent(Event* event) { target_handler()->OnEvent(event); }
- bool CanAcceptEvent(const Event& event) override { return true; }
- EventTarget* GetParentTarget() override { return nullptr; }
- std::unique_ptr<EventTargetIterator> GetChildIterator() const override {
- return base::WrapUnique(new TestEventTargetIterator);
- }
- EventTargeter* GetEventTargeter() override { return nullptr; }
- private:
- std::unique_ptr<EventHandler> target_handler_;
- std::unique_ptr<EventHandler> delegate_;
- };
- // An EventHandler that sets itself as a target handler for an EventTarget and
- // can recursively dispatch an Event.
- class NestedEventHandler : public EventHandler {
- public:
- NestedEventHandler(TestEventTarget* target, int nesting)
- : target_(target), nesting_(nesting) {
- original_handler_ = target_->SetTargetHandler(this);
- }
- NestedEventHandler(const NestedEventHandler&) = delete;
- NestedEventHandler& operator=(const NestedEventHandler&) = delete;
- ~NestedEventHandler() override {
- EventHandler* handler = target_->SetTargetHandler(original_handler_);
- DCHECK_EQ(this, handler);
- }
- protected:
- void OnEvent(Event* event) override {
- if (--nesting_ == 0)
- return;
- target_->DispatchEvent(event);
- }
- private:
- raw_ptr<TestEventTarget> target_;
- int nesting_;
- raw_ptr<EventHandler> original_handler_;
- };
- // An EventHandler that sets itself as a target handler for an EventTarget and
- // destroys that EventTarget when handling an Event, possibly after recursively
- // handling the Event.
- class TargetDestroyingEventHandler : public EventHandler {
- public:
- TargetDestroyingEventHandler(TestEventTarget* target, int nesting)
- : target_(target), nesting_(nesting) {
- original_handler_ = target_->SetTargetHandler(this);
- }
- TargetDestroyingEventHandler(const TargetDestroyingEventHandler&) = delete;
- TargetDestroyingEventHandler& operator=(const TargetDestroyingEventHandler&) =
- delete;
- ~TargetDestroyingEventHandler() override {
- EventHandler* handler = target_->SetTargetHandler(original_handler_);
- DCHECK_EQ(this, handler);
- }
- protected:
- void OnEvent(Event* event) override {
- if (--nesting_ == 0) {
- delete target_;
- return;
- }
- target_->DispatchEvent(event);
- }
- private:
- raw_ptr<TestEventTarget> target_;
- int nesting_;
- raw_ptr<EventHandler> original_handler_;
- };
- // An EventHandler that can be set to receive events in addition to the target
- // handler and counts the Events that it receives.
- class EventCountingEventHandler : public EventHandler {
- public:
- EventCountingEventHandler(EventTarget* target, int* count)
- : scoped_target_handler_(new ScopedTargetHandler(target, this)),
- count_(count) {}
- EventCountingEventHandler(const EventCountingEventHandler&) = delete;
- EventCountingEventHandler& operator=(const EventCountingEventHandler&) =
- delete;
- ~EventCountingEventHandler() override {}
- protected:
- void OnEvent(Event* event) override { (*count_)++; }
- private:
- std::unique_ptr<ScopedTargetHandler> scoped_target_handler_;
- raw_ptr<int> count_;
- };
- // An EventCountingEventHandler that will also mark the event to stop further
- // propataion.
- class EventStopPropagationHandler : public EventCountingEventHandler {
- public:
- EventStopPropagationHandler(EventTarget* target, int* count)
- : EventCountingEventHandler(target, count) {}
- EventStopPropagationHandler(const EventStopPropagationHandler&) = delete;
- EventStopPropagationHandler& operator=(const EventStopPropagationHandler&) =
- delete;
- ~EventStopPropagationHandler() override {}
- protected:
- void OnEvent(Event* event) override {
- EventCountingEventHandler::OnEvent(event);
- event->StopPropagation();
- }
- };
- } // namespace
- // Tests that a ScopedTargetHandler invokes both the target and a delegate.
- TEST(ScopedTargetHandlerTest, HandlerInvoked) {
- int count = 0;
- std::unique_ptr<TestEventTarget> target = std::make_unique<TestEventTarget>();
- std::unique_ptr<NestedEventHandler> target_handler(
- new NestedEventHandler(target.get(), 1));
- std::unique_ptr<EventCountingEventHandler> delegate(
- new EventCountingEventHandler(target.get(), &count));
- target->SetHandler(std::move(target_handler), std::move(delegate));
- MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
- EF_LEFT_MOUSE_BUTTON);
- target->DispatchEvent(&event);
- EXPECT_EQ(1, count);
- }
- // Tests that a ScopedTargetHandler invokes both the target and a delegate but
- // does not further propagate the event after a handler stops event propagation.
- TEST(ScopedTargetHandlerTest, HandlerInvokedOnceThenEventStopsPropagating) {
- int count = 0;
- std::unique_ptr<TestEventTarget> target = std::make_unique<TestEventTarget>();
- std::unique_ptr<NestedEventHandler> target_handler(
- new NestedEventHandler(target.get(), 3));
- std::unique_ptr<EventStopPropagationHandler> delegate(
- new EventStopPropagationHandler(target.get(), &count));
- target->SetHandler(std::move(target_handler), std::move(delegate));
- MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
- EF_LEFT_MOUSE_BUTTON);
- target->DispatchEvent(&event);
- EXPECT_EQ(1, count);
- }
- // Tests that a ScopedTargetHandler invokes both the target and a delegate when
- // an Event is dispatched recursively such as with synthetic events.
- TEST(ScopedTargetHandlerTest, HandlerInvokedNested) {
- int count = 0;
- std::unique_ptr<TestEventTarget> target = std::make_unique<TestEventTarget>();
- std::unique_ptr<NestedEventHandler> target_handler(
- new NestedEventHandler(target.get(), 2));
- std::unique_ptr<EventCountingEventHandler> delegate(
- new EventCountingEventHandler(target.get(), &count));
- target->SetHandler(std::move(target_handler), std::move(delegate));
- MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
- EF_LEFT_MOUSE_BUTTON);
- target->DispatchEvent(&event);
- EXPECT_EQ(2, count);
- }
- // Tests that a it is safe to delete a ScopedTargetHandler while handling an
- // event.
- TEST(ScopedTargetHandlerTest, SafeToDestroy) {
- int count = 0;
- TestEventTarget* target = new TestEventTarget;
- std::unique_ptr<TargetDestroyingEventHandler> target_handler(
- new TargetDestroyingEventHandler(target, 1));
- std::unique_ptr<EventCountingEventHandler> delegate(
- new EventCountingEventHandler(target, &count));
- target->SetHandler(std::move(target_handler), std::move(delegate));
- MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
- EF_LEFT_MOUSE_BUTTON);
- target->DispatchEvent(&event);
- EXPECT_EQ(0, count);
- }
- // Tests that a it is safe to delete a ScopedTargetHandler while handling an
- // event recursively.
- TEST(ScopedTargetHandlerTest, SafeToDestroyNested) {
- int count = 0;
- TestEventTarget* target = new TestEventTarget;
- std::unique_ptr<TargetDestroyingEventHandler> target_handler(
- new TargetDestroyingEventHandler(target, 2));
- std::unique_ptr<EventCountingEventHandler> delegate(
- new EventCountingEventHandler(target, &count));
- target->SetHandler(std::move(target_handler), std::move(delegate));
- MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
- EF_LEFT_MOUSE_BUTTON);
- target->DispatchEvent(&event);
- EXPECT_EQ(0, count);
- }
- } // namespace ui
|