123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // Copyright 2014 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/views/event_monitor.h"
- #include <utility>
- #include "base/memory/raw_ptr.h"
- #include "ui/events/event_observer.h"
- #include "ui/events/test/event_generator.h"
- #include "ui/views/test/widget_test.h"
- #include "ui/views/widget/widget_utils.h"
- #if defined(USE_AURA)
- #include "ui/aura/window.h"
- #endif
- namespace views {
- namespace test {
- // A simple event observer that records the number of events.
- class TestEventObserver : public ui::EventObserver {
- public:
- TestEventObserver() = default;
- TestEventObserver(const TestEventObserver&) = delete;
- TestEventObserver& operator=(const TestEventObserver&) = delete;
- ~TestEventObserver() override = default;
- // ui::EventObserver:
- void OnEvent(const ui::Event& event) override { ++observed_event_count_; }
- size_t observed_event_count() const { return observed_event_count_; }
- private:
- size_t observed_event_count_ = 0;
- };
- class EventMonitorTest : public WidgetTest {
- public:
- EventMonitorTest() = default;
- EventMonitorTest(const EventMonitorTest&) = delete;
- EventMonitorTest& operator=(const EventMonitorTest&) = delete;
- // testing::Test:
- void SetUp() override {
- WidgetTest::SetUp();
- widget_ = CreateTopLevelNativeWidget();
- widget_->SetSize(gfx::Size(100, 100));
- widget_->Show();
- generator_ = std::make_unique<ui::test::EventGenerator>(
- GetContext(), widget_->GetNativeWindow());
- generator_->set_target(ui::test::EventGenerator::Target::APPLICATION);
- }
- void TearDown() override {
- widget_->CloseNow();
- WidgetTest::TearDown();
- }
- protected:
- raw_ptr<Widget> widget_ = nullptr;
- std::unique_ptr<ui::test::EventGenerator> generator_;
- TestEventObserver observer_;
- };
- TEST_F(EventMonitorTest, ShouldReceiveAppEventsWhileInstalled) {
- std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateApplicationMonitor(
- &observer_, widget_->GetNativeWindow(),
- {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED}));
- generator_->ClickLeftButton();
- EXPECT_EQ(2u, observer_.observed_event_count());
- monitor.reset();
- generator_->ClickLeftButton();
- EXPECT_EQ(2u, observer_.observed_event_count());
- }
- TEST_F(EventMonitorTest, ShouldReceiveWindowEventsWhileInstalled) {
- std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
- &observer_, widget_->GetNativeWindow(),
- {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED}));
- generator_->ClickLeftButton();
- EXPECT_EQ(2u, observer_.observed_event_count());
- monitor.reset();
- generator_->ClickLeftButton();
- EXPECT_EQ(2u, observer_.observed_event_count());
- }
- TEST_F(EventMonitorTest, ShouldNotReceiveEventsFromOtherWindow) {
- Widget* widget2 = CreateTopLevelNativeWidget();
- std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
- &observer_, widget2->GetNativeWindow(),
- {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED}));
- generator_->ClickLeftButton();
- EXPECT_EQ(0u, observer_.observed_event_count());
- monitor.reset();
- widget2->CloseNow();
- }
- TEST_F(EventMonitorTest, ShouldOnlyReceiveRequestedEventTypes) {
- // This event monitor only listens to mouse press, not release.
- std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
- &observer_, widget_->GetNativeWindow(), {ui::ET_MOUSE_PRESSED}));
- generator_->ClickLeftButton();
- EXPECT_EQ(1u, observer_.observed_event_count());
- monitor.reset();
- }
- TEST_F(EventMonitorTest, WindowMonitorTornDownOnWindowClose) {
- Widget* widget2 = CreateTopLevelNativeWidget();
- widget2->Show();
- std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
- &observer_, widget2->GetNativeWindow(), {ui::ET_MOUSE_PRESSED}));
- // Closing the widget before destroying the monitor should not crash.
- widget2->CloseNow();
- monitor.reset();
- }
- namespace {
- class DeleteOtherOnEventObserver : public ui::EventObserver {
- public:
- explicit DeleteOtherOnEventObserver(gfx::NativeWindow context) {
- monitor_ = EventMonitor::CreateApplicationMonitor(
- this, context, {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED});
- }
- DeleteOtherOnEventObserver(const DeleteOtherOnEventObserver&) = delete;
- DeleteOtherOnEventObserver& operator=(const DeleteOtherOnEventObserver&) =
- delete;
- bool DidDelete() const { return !observer_to_delete_; }
- void set_monitor_to_delete(
- std::unique_ptr<DeleteOtherOnEventObserver> observer_to_delete) {
- observer_to_delete_ = std::move(observer_to_delete);
- }
- // ui::EventObserver:
- void OnEvent(const ui::Event& event) override {
- observer_to_delete_ = nullptr;
- }
- private:
- std::unique_ptr<EventMonitor> monitor_;
- std::unique_ptr<DeleteOtherOnEventObserver> observer_to_delete_;
- };
- } // namespace
- // Ensure correct behavior when an event monitor is removed while iterating
- // over the OS-controlled observer list.
- TEST_F(EventMonitorTest, TwoMonitors) {
- gfx::NativeWindow window = widget_->GetNativeWindow();
- auto deleter = std::make_unique<DeleteOtherOnEventObserver>(window);
- auto deletee = std::make_unique<DeleteOtherOnEventObserver>(window);
- deleter->set_monitor_to_delete(std::move(deletee));
- EXPECT_FALSE(deleter->DidDelete());
- generator_->PressLeftButton();
- EXPECT_TRUE(deleter->DidDelete());
- // Now try setting up observers in the alternate order.
- deletee = std::make_unique<DeleteOtherOnEventObserver>(window);
- deleter = std::make_unique<DeleteOtherOnEventObserver>(window);
- deleter->set_monitor_to_delete(std::move(deletee));
- EXPECT_FALSE(deleter->DidDelete());
- generator_->ReleaseLeftButton();
- EXPECT_TRUE(deleter->DidDelete());
- }
- } // namespace test
- } // namespace views
|