Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Unified Diff: components/mus/ws/event_dispatcher_unittest.cc

Issue 1605773004: mus: Implement Window Server Capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698