| Index: components/mus/ws/event_dispatcher_unittest.cc
|
| diff --git a/components/mus/ws/event_dispatcher_unittest.cc b/components/mus/ws/event_dispatcher_unittest.cc
|
| index 04255ab74f2396734bea3ce932b123c94bf0e8e0..fb0c5297fda17f63cc847f75c9de404573147af1 100644
|
| --- a/components/mus/ws/event_dispatcher_unittest.cc
|
| +++ b/components/mus/ws/event_dispatcher_unittest.cc
|
| @@ -35,7 +35,10 @@ struct DispatchedEventDetails {
|
| class TestEventDispatcherDelegate : public EventDispatcherDelegate {
|
| public:
|
| explicit TestEventDispatcherDelegate(ServerWindow* root)
|
| - : root_(root), focused_window_(nullptr), last_accelerator_(0) {}
|
| + : root_(root),
|
| + focused_window_(nullptr),
|
| + lost_capture_window_(nullptr),
|
| + last_accelerator_(0) {}
|
| ~TestEventDispatcherDelegate() override {}
|
|
|
| uint32_t GetAndClearLastAccelerator() {
|
| @@ -62,6 +65,7 @@ class TestEventDispatcherDelegate : public EventDispatcherDelegate {
|
| }
|
|
|
| bool has_queued_events() const { return !dispatched_event_queue_.empty(); }
|
| + ServerWindow* lost_capture_window() { return lost_capture_window_; }
|
|
|
| private:
|
| // EventDispatcherDelegate:
|
| @@ -75,6 +79,9 @@ class TestEventDispatcherDelegate : public EventDispatcherDelegate {
|
| ServerWindow* GetFocusedWindowForEventDispatcher() override {
|
| return focused_window_;
|
| }
|
| + void OnLostCapture(ServerWindow* window) override {
|
| + lost_capture_window_ = window;
|
| + }
|
| void DispatchInputEventToWindow(ServerWindow* target,
|
| bool in_nonclient_area,
|
| mojom::EventPtr event) override {
|
| @@ -87,6 +94,7 @@ class TestEventDispatcherDelegate : public EventDispatcherDelegate {
|
|
|
| ServerWindow* root_;
|
| ServerWindow* focused_window_;
|
| + ServerWindow* lost_capture_window_;
|
| uint32_t last_accelerator_;
|
| std::queue<scoped_ptr<DispatchedEventDetails>> dispatched_event_queue_;
|
|
|
| @@ -158,50 +166,123 @@ void RunMouseEventTests(EventDispatcher* dispatcher,
|
|
|
| } // namespace
|
|
|
| -TEST(EventDispatcherTest, ProcessEvent) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +// Test fixture for EventDispatcher with friend access to verify the internal
|
| +// state. Setup creates a TestServerWindowDelegate, a visible root ServerWindow,
|
| +// a TestEventDispatcher and the EventDispatcher for testing.
|
| +class EventDispatcherTest : public testing::Test {
|
| + public:
|
| + EventDispatcherTest() {}
|
| + ~EventDispatcherTest() override {}
|
| +
|
| + ServerWindow* root_window() { return root_window_.get(); }
|
| + TestEventDispatcherDelegate* test_event_dispatcher_delegate() {
|
| + return test_event_dispatcher_delegate_.get();
|
| + }
|
| + EventDispatcher* event_dispatcher() { return event_dispatcher_.get(); }
|
|
|
| - ServerWindow child(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child);
|
| - child.SetVisible(true);
|
| - EnableHitTest(&child);
|
| + bool AreAnyPointersDown() const;
|
| + // Deletes everything created during SetUp()
|
| + void ClearSetup();
|
| + // Creates a window which is a child of |root_window_|. It is not owned by
|
| + // EventDispatcherTest.
|
| + ServerWindow* CreateChildWindow(const WindowId& id);
|
| + bool IsWindowPointerTarget(ServerWindow* window) const;
|
| + int NumberPointerTargetsForWindow(ServerWindow* window) const;
|
|
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + protected:
|
| + // testing::Test:
|
| + void SetUp() override;
|
|
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + private:
|
| + scoped_ptr<TestServerWindowDelegate> window_delegate_;
|
| + scoped_ptr<ServerWindow> root_window_;
|
| + scoped_ptr<TestEventDispatcherDelegate> test_event_dispatcher_delegate_;
|
| + scoped_ptr<EventDispatcher> event_dispatcher_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EventDispatcherTest);
|
| +};
|
| +
|
| +bool EventDispatcherTest::AreAnyPointersDown() const {
|
| + return event_dispatcher_->AreAnyPointersDown();
|
| +}
|
| +
|
| +void EventDispatcherTest::ClearSetup() {
|
| + window_delegate_.reset();
|
| + root_window_.reset();
|
| + test_event_dispatcher_delegate_.reset();
|
| + event_dispatcher_.reset();
|
| +}
|
| +
|
| +ServerWindow* EventDispatcherTest::CreateChildWindow(const WindowId& id) {
|
| + ServerWindow* child = new ServerWindow(window_delegate_.get(), id);
|
| + root_window_->Add(child);
|
| + child->SetVisible(true);
|
| + EnableHitTest(child);
|
| + return child;
|
| +}
|
| +
|
| +bool EventDispatcherTest::IsWindowPointerTarget(ServerWindow* window) const {
|
| + return event_dispatcher_->IsObservingWindow(window);
|
| +}
|
| +
|
| +int EventDispatcherTest::NumberPointerTargetsForWindow(
|
| + ServerWindow* window) const {
|
| + int count = 0;
|
| + for (const auto& pair : event_dispatcher_->pointer_targets_)
|
| + if (pair.second.window == window)
|
| + count++;
|
| + return count;
|
| +}
|
| +
|
| +void EventDispatcherTest::SetUp() {
|
| + testing::Test::SetUp();
|
| +
|
| + window_delegate_.reset(new TestServerWindowDelegate());
|
| + root_window_.reset(new ServerWindow(window_delegate_.get(), WindowId(1, 2)));
|
| + window_delegate_->set_root_window(root_window_.get());
|
| + root_window_->SetVisible(true);
|
| +
|
| + test_event_dispatcher_delegate_.reset(
|
| + new TestEventDispatcherDelegate(root_window_.get()));
|
| + event_dispatcher_.reset(
|
| + new EventDispatcher(test_event_dispatcher_delegate_.get()));
|
| + event_dispatcher_->set_root(root_window_.get());
|
| +}
|
| +
|
| +TEST_F(EventDispatcherTest, ProcessEvent) {
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
| +
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| // Send event that is over child.
|
| const ui::MouseEvent ui_event(
|
| ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + event_dispatcher()->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(ui_event)));
|
|
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| -
|
| + test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails();
|
| ASSERT_TRUE(details);
|
| - ASSERT_EQ(&child, details->window);
|
| + ASSERT_EQ(child.get(), details->window);
|
|
|
| scoped_ptr<ui::Event> dispatched_event(
|
| details->event.To<scoped_ptr<ui::Event>>());
|
| ASSERT_TRUE(dispatched_event);
|
| ASSERT_TRUE(dispatched_event->IsMouseEvent());
|
| +
|
| ui::MouseEvent* dispatched_mouse_event =
|
| static_cast<ui::MouseEvent*>(dispatched_event.get());
|
| EXPECT_EQ(gfx::Point(20, 25), dispatched_mouse_event->root_location());
|
| EXPECT_EQ(gfx::Point(10, 15), dispatched_mouse_event->location());
|
| }
|
|
|
| -TEST(EventDispatcherTest, AcceleratorBasic) {
|
| +TEST_F(EventDispatcherTest, AcceleratorBasic) {
|
| + ClearSetup();
|
| TestEventDispatcherDelegate event_dispatcher_delegate(nullptr);
|
| EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| +
|
| uint32_t accelerator_1 = 1;
|
| mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher(
|
| mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown);
|
| @@ -235,87 +316,74 @@ TEST(EventDispatcherTest, AcceleratorBasic) {
|
| EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_3, std::move(matcher)));
|
| }
|
|
|
| -TEST(EventDispatcherTest, EventMatching) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| +TEST_F(EventDispatcherTest, EventMatching) {
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
|
|
| mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher(
|
| mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown);
|
| uint32_t accelerator_1 = 1;
|
| - dispatcher.AddAccelerator(accelerator_1, std::move(matcher));
|
| + dispatcher->AddAccelerator(accelerator_1, std::move(matcher));
|
|
|
| ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN);
|
| - dispatcher.ProcessEvent(mojom::Event::From(key));
|
| + dispatcher->ProcessEvent(mojom::Event::From(key));
|
| EXPECT_EQ(accelerator_1,
|
| - event_dispatcher_delegate.GetAndClearLastAccelerator());
|
| + event_dispatcher_delegate->GetAndClearLastAccelerator());
|
|
|
| // EF_NUM_LOCK_ON should be ignored since CreateKeyMatcher defaults to
|
| // ignoring.
|
| key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W,
|
| ui::EF_CONTROL_DOWN | ui::EF_NUM_LOCK_ON);
|
| - dispatcher.ProcessEvent(mojom::Event::From(key));
|
| + dispatcher->ProcessEvent(mojom::Event::From(key));
|
| EXPECT_EQ(accelerator_1,
|
| - event_dispatcher_delegate.GetAndClearLastAccelerator());
|
| + event_dispatcher_delegate->GetAndClearLastAccelerator());
|
|
|
| key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_NONE);
|
| - dispatcher.ProcessEvent(mojom::Event::From(key));
|
| - EXPECT_EQ(0u, event_dispatcher_delegate.GetAndClearLastAccelerator());
|
| + dispatcher->ProcessEvent(mojom::Event::From(key));
|
| + EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator());
|
|
|
| uint32_t accelerator_2 = 2;
|
| matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::W,
|
| mus::mojom::kEventFlagNone);
|
| - dispatcher.AddAccelerator(accelerator_2, std::move(matcher));
|
| - dispatcher.ProcessEvent(mojom::Event::From(key));
|
| + dispatcher->AddAccelerator(accelerator_2, std::move(matcher));
|
| + dispatcher->ProcessEvent(mojom::Event::From(key));
|
| EXPECT_EQ(accelerator_2,
|
| - event_dispatcher_delegate.GetAndClearLastAccelerator());
|
| + event_dispatcher_delegate->GetAndClearLastAccelerator());
|
|
|
| - dispatcher.RemoveAccelerator(accelerator_2);
|
| - dispatcher.ProcessEvent(mojom::Event::From(key));
|
| - EXPECT_EQ(0u, event_dispatcher_delegate.GetAndClearLastAccelerator());
|
| + dispatcher->RemoveAccelerator(accelerator_2);
|
| + dispatcher->ProcessEvent(mojom::Event::From(key));
|
| + EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator());
|
| }
|
|
|
| -TEST(EventDispatcherTest, Capture) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +TEST_F(EventDispatcherTest, Capture) {
|
| + ServerWindow* root = root_window();
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
|
|
| - ServerWindow child(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child);
|
| - child.SetVisible(true);
|
| -
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| - EnableHitTest(&child);
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + root->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| MouseEventTest tests[] = {
|
| // Send a mouse down event over child.
|
| {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25),
|
| gfx::Point(20, 25), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| - &child, gfx::Point(20, 25), gfx::Point(10, 15), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(20, 25), gfx::Point(10, 15), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
|
|
| // Capture should be activated. Let's send a mouse move outside the bounds
|
| // of the child.
|
| {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50),
|
| gfx::Point(50, 50), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| - &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
| // Release the mouse and verify that the mouse up event goes to the child.
|
| {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50),
|
| gfx::Point(50, 50), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| - &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
|
|
| // A mouse move at (50, 50) should now go to the root window. As the
|
| // move crosses between |child| and |root| |child| gets an exit, and
|
| @@ -323,47 +391,35 @@ TEST(EventDispatcherTest, Capture) {
|
| {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50),
|
| gfx::Point(50, 50), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| - &child, gfx::Point(50, 50), gfx::Point(40, 40), &root,
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40), root,
|
| gfx::Point(50, 50), gfx::Point(50, 50)},
|
|
|
| };
|
| - RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests,
|
| - arraysize(tests));
|
| + RunMouseEventTests(event_dispatcher(), test_event_dispatcher_delegate(),
|
| + tests, arraysize(tests));
|
| }
|
|
|
| -TEST(EventDispatcherTest, CaptureMultipleMouseButtons) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +TEST_F(EventDispatcherTest, CaptureMultipleMouseButtons) {
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
|
|
| - ServerWindow child(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child);
|
| - child.SetVisible(true);
|
| - EnableHitTest(&child);
|
| -
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| MouseEventTest tests[] = {
|
| // Send a mouse down event over child with a left mouse button
|
| {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25),
|
| gfx::Point(20, 25), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| - &child, gfx::Point(20, 25), gfx::Point(10, 15), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(20, 25), gfx::Point(10, 15), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
|
|
| // Capture should be activated. Let's send a mouse move outside the bounds
|
| // of the child and press the right mouse button too.
|
| {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50),
|
| gfx::Point(50, 50), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, 0),
|
| - &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
|
|
| // Release the left mouse button and verify that the mouse up event goes
|
| // to the child.
|
| @@ -371,80 +427,72 @@ TEST(EventDispatcherTest, CaptureMultipleMouseButtons) {
|
| gfx::Point(50, 50), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON,
|
| ui::EF_RIGHT_MOUSE_BUTTON),
|
| - &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
|
|
| // A mouse move at (50, 50) should still go to the child.
|
| {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50),
|
| gfx::Point(50, 50), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, 0),
|
| - &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
|
|
| };
|
| - RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests,
|
| - arraysize(tests));
|
| + RunMouseEventTests(event_dispatcher(), test_event_dispatcher_delegate(),
|
| + tests, arraysize(tests));
|
| }
|
|
|
| -TEST(EventDispatcherTest, ClientAreaGoesToOwner) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +TEST_F(EventDispatcherTest, ClientAreaGoesToOwner) {
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
|
|
| - ServerWindow child(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child);
|
| - child.SetVisible(true);
|
| - EnableHitTest(&child);
|
| -
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| - child.SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>());
|
| + child->SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>());
|
|
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
|
|
| // Start move loop by sending mouse event over non-client area.
|
| const ui::MouseEvent press_event(
|
| ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
|
|
| // Events should target child and be in the non-client area.
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| ASSERT_TRUE(details);
|
| - ASSERT_EQ(&child, details->window);
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_TRUE(details->in_nonclient_area);
|
|
|
| // Move the mouse 5,6 pixels and target is the same.
|
| const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(17, 18),
|
| gfx::Point(17, 18), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, 0);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(move_event)));
|
|
|
| // Still same target.
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - ASSERT_EQ(&child, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_TRUE(details->in_nonclient_area);
|
|
|
| // Release the mouse.
|
| const ui::MouseEvent release_event(
|
| ui::ET_MOUSE_RELEASED, gfx::Point(17, 18), gfx::Point(17, 18),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(release_event)));
|
|
|
| // The event should not have been dispatched to the delegate.
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - ASSERT_EQ(&child, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_TRUE(details->in_nonclient_area);
|
|
|
| // Press in the client area and verify target/client area. The non-client area
|
| @@ -452,211 +500,169 @@ TEST(EventDispatcherTest, ClientAreaGoesToOwner) {
|
| const ui::MouseEvent press_event2(
|
| ui::ET_MOUSE_PRESSED, gfx::Point(21, 22), gfx::Point(21, 22),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(press_event2)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_TRUE(event_dispatcher_delegate.has_queued_events());
|
| - ASSERT_EQ(&child, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_TRUE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_TRUE(details->in_nonclient_area);
|
| EXPECT_EQ(mojom::EventType::MOUSE_EXIT, details->event->action);
|
|
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - ASSERT_EQ(&child, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_FALSE(details->in_nonclient_area);
|
| EXPECT_EQ(mojom::EventType::POINTER_DOWN, details->event->action);
|
| }
|
|
|
| -TEST(EventDispatcherTest, AdditionalClientArea) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +TEST_F(EventDispatcherTest, AdditionalClientArea) {
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
|
|
| - ServerWindow child(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child);
|
| - child.SetVisible(true);
|
| - EnableHitTest(&child);
|
| -
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| std::vector<gfx::Rect> additional_client_areas;
|
| additional_client_areas.push_back(gfx::Rect(18, 0, 2, 2));
|
| - child.SetClientArea(gfx::Insets(5, 5, 5, 5), additional_client_areas);
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + child->SetClientArea(gfx::Insets(5, 5, 5, 5), additional_client_areas);
|
|
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| // Press in the additional client area, it should go to the child.
|
| const ui::MouseEvent press_event(
|
| ui::ET_MOUSE_PRESSED, gfx::Point(28, 11), gfx::Point(28, 11),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + event_dispatcher()->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
|
|
| // Events should target child and be in the client area.
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - ASSERT_EQ(&child, details->window);
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_FALSE(details->in_nonclient_area);
|
| }
|
|
|
| -TEST(EventDispatcherTest, DontFocusOnSecondDown) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| -
|
| - ServerWindow child1(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child1);
|
| - child1.SetVisible(true);
|
| - EnableHitTest(&child1);
|
| +TEST_F(EventDispatcherTest, DontFocusOnSecondDown) {
|
| + scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3)));
|
| + scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4)));
|
|
|
| - ServerWindow child2(&window_delegate, WindowId(1, 4));
|
| - root.Add(&child2);
|
| - child2.SetVisible(true);
|
| - EnableHitTest(&child2);
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child1->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + child2->SetBounds(gfx::Rect(50, 51, 11, 12));
|
|
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child1.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| - child2.SetBounds(gfx::Rect(50, 51, 11, 12));
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
|
|
| // Press on child1. First press event should change focus.
|
| const ui::MouseEvent press_event(
|
| ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - EXPECT_EQ(&child1, details->window);
|
| - EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastFocusedWindow());
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + EXPECT_EQ(child1.get(), details->window);
|
| + EXPECT_EQ(child1.get(),
|
| + event_dispatcher_delegate->GetAndClearLastFocusedWindow());
|
|
|
| // Press (with a different pointer id) on child2. Event should go to child2,
|
| // but focus should not change.
|
| const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(53, 54), 2,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(touch_event)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - EXPECT_EQ(&child2, details->window);
|
| - EXPECT_EQ(nullptr, event_dispatcher_delegate.GetAndClearLastFocusedWindow());
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + EXPECT_EQ(child2.get(), details->window);
|
| + EXPECT_EQ(nullptr, event_dispatcher_delegate->GetAndClearLastFocusedWindow());
|
| }
|
|
|
| -TEST(EventDispatcherTest, TwoPointersActive) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +TEST_F(EventDispatcherTest, TwoPointersActive) {
|
| + scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3)));
|
| + scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4)));
|
|
|
| - ServerWindow child1(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child1);
|
| - child1.SetVisible(true);
|
| - EnableHitTest(&child1);
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child1->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + child2->SetBounds(gfx::Rect(50, 51, 11, 12));
|
|
|
| - ServerWindow child2(&window_delegate, WindowId(1, 4));
|
| - root.Add(&child2);
|
| - child2.SetVisible(true);
|
| - EnableHitTest(&child2);
|
| -
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child1.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| - child2.SetBounds(gfx::Rect(50, 51, 11, 12));
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
|
|
| // Press on child1.
|
| const ui::TouchEvent touch_event1(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), 1,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(touch_event1)));
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child1, details->window);
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child1.get(), details->window);
|
|
|
| // Drag over child2, child1 should get the drag.
|
| const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::Point(53, 54), 1,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(drag_event1)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child1, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child1.get(), details->window);
|
|
|
| // Press on child2 with a different touch id.
|
| const ui::TouchEvent touch_event2(ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), 2,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(touch_event2)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child2, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child2.get(), details->window);
|
|
|
| // Drag over child1 with id 2, child2 should continue to get the drag.
|
| const ui::TouchEvent drag_event2(ui::ET_TOUCH_MOVED, gfx::Point(13, 14), 2,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(drag_event2)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child2, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child2.get(), details->window);
|
|
|
| // Drag again with id 1, child1 should continue to get it.
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(drag_event1)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child1, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child1.get(), details->window);
|
|
|
| // Release touch id 1, and click on 2. 2 should get it.
|
| const ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, gfx::Point(54, 55),
|
| 1, base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(touch_release)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child1, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child1.get(), details->window);
|
| const ui::TouchEvent touch_event3(ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), 2,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(touch_event3)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&child2, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(child2.get(), details->window);
|
| }
|
|
|
| -TEST(EventDispatcherTest, DestroyWindowWhileGettingEvents) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| -
|
| - scoped_ptr<ServerWindow> child(
|
| - new ServerWindow(&window_delegate, WindowId(1, 3)));
|
| - root.Add(child.get());
|
| - child->SetVisible(true);
|
| - EnableHitTest(child.get());
|
| +TEST_F(EventDispatcherTest, DestroyWindowWhileGettingEvents) {
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
|
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
|
|
| // Press on child.
|
| const ui::TouchEvent touch_event1(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), 1,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(touch_event1)));
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| EXPECT_EQ(child.get(), details->window);
|
|
|
| // Delete child, and continue the drag. Event should not be dispatched.
|
| @@ -664,65 +670,58 @@ TEST(EventDispatcherTest, DestroyWindowWhileGettingEvents) {
|
|
|
| const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::Point(53, 54), 1,
|
| base::TimeDelta());
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(drag_event1)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| EXPECT_EQ(nullptr, details.get());
|
| }
|
|
|
| -TEST(EventDispatcherTest, MouseInExtendedHitTestRegion) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| +TEST_F(EventDispatcherTest, MouseInExtendedHitTestRegion) {
|
| + ServerWindow* root = root_window();
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
|
|
| - ServerWindow child(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child);
|
| - child.SetVisible(true);
|
| - EnableHitTest(&child);
|
| + root->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
|
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
|
|
| // Send event that is not over child.
|
| const ui::MouseEvent ui_event(
|
| ui::ET_MOUSE_PRESSED, gfx::Point(8, 9), gfx::Point(8, 9),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(ui_event)));
|
| scoped_ptr<DispatchedEventDetails> details =
|
| - event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - ASSERT_EQ(&root, details->window);
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + ASSERT_EQ(root, details->window);
|
|
|
| // Release the mouse.
|
| const ui::MouseEvent release_event(
|
| ui::ET_MOUSE_RELEASED, gfx::Point(8, 9), gfx::Point(8, 9),
|
| base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| - dispatcher.ProcessEvent(
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(release_event)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| - ASSERT_EQ(&root, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(root, details->window);
|
| EXPECT_FALSE(details->in_nonclient_area);
|
|
|
| // Change the extended hit test region and send event in extended hit test
|
| // region. Should result in exit for root, followed by press for child.
|
| - child.set_extended_hit_test_region(gfx::Insets(5, 5, 5, 5));
|
| - dispatcher.ProcessEvent(
|
| + child->set_extended_hit_test_region(gfx::Insets(5, 5, 5, 5));
|
| + dispatcher->ProcessEvent(
|
| mojom::Event::From(static_cast<const ui::Event&>(ui_event)));
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| - EXPECT_EQ(&root, details->window);
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_EQ(root, details->window);
|
| EXPECT_EQ(mojom::EventType::MOUSE_EXIT, details->event->action);
|
| - details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails();
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| ASSERT_TRUE(details);
|
|
|
| - EXPECT_FALSE(event_dispatcher_delegate.has_queued_events());
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| EXPECT_TRUE(details->in_nonclient_area);
|
| - ASSERT_EQ(&child, details->window);
|
| + ASSERT_EQ(child.get(), details->window);
|
| EXPECT_EQ(mojom::EventType::POINTER_DOWN, details->event->action);
|
| scoped_ptr<ui::Event> dispatched_event(
|
| details->event.To<scoped_ptr<ui::Event>>());
|
| @@ -733,46 +732,278 @@ TEST(EventDispatcherTest, MouseInExtendedHitTestRegion) {
|
| EXPECT_EQ(gfx::Point(-2, -1), dispatched_mouse_event->location());
|
| }
|
|
|
| -TEST(EventDispatcherTest, WheelWhileDown) {
|
| - TestServerWindowDelegate window_delegate;
|
| - ServerWindow root(&window_delegate, WindowId(1, 2));
|
| - window_delegate.set_root_window(&root);
|
| - root.SetVisible(true);
|
| -
|
| - ServerWindow child1(&window_delegate, WindowId(1, 3));
|
| - root.Add(&child1);
|
| - child1.SetVisible(true);
|
| - EnableHitTest(&child1);
|
| +TEST_F(EventDispatcherTest, WheelWhileDown) {
|
| + scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3)));
|
| + scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4)));
|
|
|
| - ServerWindow child2(&window_delegate, WindowId(1, 4));
|
| - root.Add(&child2);
|
| - child2.SetVisible(true);
|
| - EnableHitTest(&child2);
|
| -
|
| - root.SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - child1.SetBounds(gfx::Rect(10, 10, 20, 20));
|
| - child2.SetBounds(gfx::Rect(50, 51, 11, 12));
|
| -
|
| - TestEventDispatcherDelegate event_dispatcher_delegate(&root);
|
| - EventDispatcher dispatcher(&event_dispatcher_delegate);
|
| - dispatcher.set_root(&root);
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child1->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + child2->SetBounds(gfx::Rect(50, 51, 11, 12));
|
|
|
| MouseEventTest tests[] = {
|
| // Send a mouse down event over child1.
|
| {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(15, 15),
|
| gfx::Point(15, 15), base::TimeDelta(),
|
| ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| - &child1, gfx::Point(15, 15), gfx::Point(5, 5), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child1.get(), gfx::Point(15, 15), gfx::Point(5, 5), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
| // Send mouse wheel over child2, should go to child1 as it has capture.
|
| {ui::MouseWheelEvent(gfx::Vector2d(1, 0), gfx::Point(53, 54),
|
| gfx::Point(53, 54), base::TimeDelta(), ui::EF_NONE,
|
| ui::EF_NONE),
|
| - &child1, gfx::Point(53, 54), gfx::Point(43, 44), nullptr, gfx::Point(),
|
| - gfx::Point()},
|
| + child1.get(), gfx::Point(53, 54), gfx::Point(43, 44), nullptr,
|
| + gfx::Point(), gfx::Point()},
|
| };
|
| - RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests,
|
| + RunMouseEventTests(event_dispatcher(), test_event_dispatcher_delegate(),
|
| + tests, arraysize(tests));
|
| +}
|
| +
|
| +// Tests that when explicit capture has been set that all events go to the
|
| +// designated window, and that when capture is cleared, events find the
|
| +// appropriate target window.
|
| +TEST_F(EventDispatcherTest, SetExplictCapture) {
|
| + ServerWindow* root = root_window();
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
| +
|
| + root->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| +
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
| +
|
| + {
|
| + // Send all pointer events to the child.
|
| + dispatcher->SetCaptureWindow(child.get(), false);
|
| +
|
| + // The mouse press should go to the child even though its outside its
|
| + // bounds.
|
| + const ui::MouseEvent press_event(
|
| + ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5),
|
| + base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| + dispatcher->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
| +
|
| + // Events should target child.
|
| + scoped_ptr<DispatchedEventDetails> details =
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| +
|
| + ASSERT_TRUE(details);
|
| + ASSERT_EQ(child.get(), details->window);
|
| + EXPECT_FALSE(details->in_nonclient_area);
|
| + }
|
| +
|
| + {
|
| + // Releasing capture and sending the same event will go to the root.
|
| + dispatcher->SetCaptureWindow(nullptr, false);
|
| + const ui::MouseEvent press_event(
|
| + ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5),
|
| + base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| + dispatcher->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
| +
|
| + // Events should target the root.
|
| + scoped_ptr<DispatchedEventDetails> details =
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| +
|
| + ASSERT_TRUE(details);
|
| + ASSERT_EQ(root, details->window);
|
| + }
|
| +}
|
| +
|
| +// This test verifies that explicit capture overrides and resets implicit
|
| +// capture.
|
| +TEST_F(EventDispatcherTest, ExplicitCaptureOverridesImplicitCapture) {
|
| + ServerWindow* root = root_window();
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
| +
|
| + root->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| +
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
| +
|
| + // Run some implicit capture tests.
|
| + MouseEventTest tests[] = {
|
| + // Send a mouse down event over child with a left mouse button
|
| + {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25),
|
| + gfx::Point(20, 25), base::TimeDelta(),
|
| + ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON),
|
| + child.get(), gfx::Point(20, 25), gfx::Point(10, 15)},
|
| + // Capture should be activated. Let's send a mouse move outside the bounds
|
| + // of the child and press the right mouse button too.
|
| + {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50),
|
| + gfx::Point(50, 50), base::TimeDelta(),
|
| + ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, 0),
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40)},
|
| + // Release the left mouse button and verify that the mouse up event goes
|
| + // to the child.
|
| + {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50),
|
| + gfx::Point(50, 50), base::TimeDelta(),
|
| + ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON,
|
| + ui::EF_RIGHT_MOUSE_BUTTON),
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40)},
|
| + // A mouse move at (50, 50) should still go to the child.
|
| + {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50),
|
| + gfx::Point(50, 50), base::TimeDelta(),
|
| + ui::EF_LEFT_MOUSE_BUTTON, 0),
|
| + child.get(), gfx::Point(50, 50), gfx::Point(40, 40)},
|
| +
|
| + };
|
| + RunMouseEventTests(dispatcher, event_dispatcher_delegate, tests,
|
| arraysize(tests));
|
| +
|
| + // Add a second pointer target to the child.
|
| + {
|
| + const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13),
|
| + 1, base::TimeDelta());
|
| + dispatcher->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(touch_event)));
|
| + }
|
| +
|
| + scoped_ptr<DispatchedEventDetails> details =
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + EXPECT_EQ(child.get(), details->window);
|
| +
|
| + // Verify that no window has explicit capture and hence we did indeed do
|
| + // implicit capture.
|
| + ASSERT_EQ(nullptr, dispatcher->capture_window());
|
| +
|
| + // Give the root window explicit capture and verify input events over the
|
| + // child go to the root instead.
|
| + dispatcher->SetCaptureWindow(root, true);
|
| +
|
| + // The implicit target should receive a cancel event for each pointer target.
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + ASSERT_TRUE(details);
|
| + EXPECT_TRUE(event_dispatcher_delegate->has_queued_events());
|
| + EXPECT_EQ(child.get(), details->window);
|
| + EXPECT_EQ(mojom::EventType::POINTER_CANCEL, details->event->action);
|
| +
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + ASSERT_TRUE(details);
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + EXPECT_EQ(child.get(), details->window);
|
| + EXPECT_EQ(mojom::EventType::POINTER_CANCEL, details->event->action);
|
| +
|
| + const ui::MouseEvent press_event(
|
| + ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), gfx::Point(15, 15),
|
| + base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| + dispatcher->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
| +
|
| + // Events should target the root.
|
| + details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + ASSERT_TRUE(details);
|
| + ASSERT_EQ(root, details->window);
|
| + ASSERT_TRUE(details->in_nonclient_area);
|
| +}
|
| +
|
| +// Tests that setting capture does delete active pointer targets for the capture
|
| +// window.
|
| +TEST_F(EventDispatcherTest, CaptureUpdatesActivePointerTargets) {
|
| + ServerWindow* root = root_window();
|
| + root->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| +
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
| + {
|
| + const ui::MouseEvent press_event(
|
| + ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5),
|
| + base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| + dispatcher->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
| +
|
| + scoped_ptr<DispatchedEventDetails> details =
|
| + test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails();
|
| + ASSERT_TRUE(details);
|
| + ASSERT_EQ(root, details->window);
|
| + }
|
| + {
|
| + const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13),
|
| + 1, base::TimeDelta());
|
| + dispatcher->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(touch_event)));
|
| + }
|
| +
|
| + ASSERT_TRUE(AreAnyPointersDown());
|
| + ASSERT_TRUE(IsWindowPointerTarget(root));
|
| + EXPECT_EQ(2, NumberPointerTargetsForWindow(root));
|
| +
|
| + // Setting the capture should clear the implicit pointers for the specified
|
| + // window.
|
| + dispatcher->SetCaptureWindow(root, true);
|
| + EXPECT_FALSE(AreAnyPointersDown());
|
| + EXPECT_FALSE(IsWindowPointerTarget(root));
|
| +}
|
| +
|
| +// Tests that when explicit capture is changed, that the previous window with
|
| +// capture is no longer being observed.
|
| +TEST_F(EventDispatcherTest, UpdatingCaptureStopsObservingPreviousCapture) {
|
| + scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3)));
|
| + scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4)));
|
| +
|
| + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| + child1->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| + child2->SetBounds(gfx::Rect(50, 51, 11, 12));
|
| +
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
| + ASSERT_FALSE(AreAnyPointersDown());
|
| + ASSERT_FALSE(IsWindowPointerTarget(child1.get()));
|
| + ASSERT_FALSE(IsWindowPointerTarget(child2.get()));
|
| + dispatcher->SetCaptureWindow(child1.get(), false);
|
| + dispatcher->SetCaptureWindow(child2.get(), false);
|
| + EXPECT_EQ(child1.get(),
|
| + test_event_dispatcher_delegate()->lost_capture_window());
|
| +
|
| + // If observing does not stop during the capture update this crashes.
|
| + child1->AddObserver(dispatcher);
|
| +}
|
| +
|
| +// Tests that destroying a window with explicit capture clears the capture
|
| +// state.
|
| +TEST_F(EventDispatcherTest, DestroyingCaptureWindowRemovesExplicitCapture) {
|
| + scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3)));
|
| + child->SetBounds(gfx::Rect(10, 10, 20, 20));
|
| +
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
| + dispatcher->SetCaptureWindow(child.get(), false);
|
| + EXPECT_EQ(child.get(), dispatcher->capture_window());
|
| +
|
| + ServerWindow* lost_capture_window = child.get();
|
| + child.reset();
|
| + EXPECT_EQ(nullptr, dispatcher->capture_window());
|
| + EXPECT_EQ(lost_capture_window,
|
| + test_event_dispatcher_delegate()->lost_capture_window());
|
| +}
|
| +
|
| +// Tests that when |in_nonclient_area| is set for a window performing capture,
|
| +// that this preference is used regardless of whether an event targets the
|
| +// client region.
|
| +TEST_F(EventDispatcherTest, CaptureInNonClientAreaOverridesActualPoint) {
|
| + ServerWindow* root = root_window();
|
| + root->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| +
|
| + root->SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>());
|
| + EventDispatcher* dispatcher = event_dispatcher();
|
| + dispatcher->SetCaptureWindow(root, true);
|
| +
|
| + TestEventDispatcherDelegate* event_dispatcher_delegate =
|
| + test_event_dispatcher_delegate();
|
| + // Press in the client area, it should be marked as non client.
|
| + const ui::MouseEvent press_event(
|
| + ui::ET_MOUSE_PRESSED, gfx::Point(6, 6), gfx::Point(6, 6),
|
| + base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
|
| + event_dispatcher()->ProcessEvent(
|
| + mojom::Event::From(static_cast<const ui::Event&>(press_event)));
|
| +
|
| + // Events should target child and be in the client area.
|
| + scoped_ptr<DispatchedEventDetails> details =
|
| + event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails();
|
| + EXPECT_FALSE(event_dispatcher_delegate->has_queued_events());
|
| + ASSERT_EQ(root, details->window);
|
| + EXPECT_TRUE(details->in_nonclient_area);
|
| }
|
|
|
| } // namespace ws
|
|
|