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 |