| Index: components/mus/ws/window_tree_unittest.cc
|
| diff --git a/components/mus/ws/window_tree_unittest.cc b/components/mus/ws/window_tree_unittest.cc
|
| index f5bd32129697c1ef2e2524b599d698e0e46f1982..510c1b4cb9ab05f90455a3dc8b287c6c331f0128 100644
|
| --- a/components/mus/ws/window_tree_unittest.cc
|
| +++ b/components/mus/ws/window_tree_unittest.cc
|
| @@ -87,6 +87,13 @@ ServerWindow* GetCaptureWindow(Display* display) {
|
| return display->GetActiveWindowManagerState()->capture_window();
|
| }
|
|
|
| +mojom::EventMatcherPtr CreateEventMatcher(mojom::EventType type) {
|
| + mojom::EventMatcherPtr matcher = mojom::EventMatcher::New();
|
| + matcher->type_matcher = mojom::EventTypeMatcher::New();
|
| + matcher->type_matcher->type = type;
|
| + return matcher;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // -----------------------------------------------------------------------------
|
| @@ -167,6 +174,7 @@ class WindowTreeTest : public testing::Test {
|
| display_binding_ = new TestDisplayBinding(display_, window_server_.get());
|
| display_->Init(make_scoped_ptr(display_binding_));
|
| wm_client_ = delegate_.last_client();
|
| + wm_client_->tracker()->changes()->clear();
|
| }
|
|
|
| protected:
|
| @@ -205,6 +213,7 @@ void WindowTreeTest::SetupEventTargeting(TestWindowTreeClient** out_client,
|
| WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window);
|
| ASSERT_TRUE(tree1 != nullptr);
|
| ASSERT_NE(tree1, wm_tree());
|
| + WindowTreeTestApi(tree1).set_user_id(wm_tree()->user_id());
|
|
|
| embed_window->SetBounds(gfx::Rect(0, 0, 50, 50));
|
|
|
| @@ -306,7 +315,7 @@ TEST_F(WindowTreeTest, FocusOnPointer) {
|
| EXPECT_EQ(child1, display_->GetFocusedWindow());
|
| ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u)
|
| << SingleChangeToDescription(*wm_client()->tracker()->changes());
|
| - EXPECT_EQ("InputEvent window=0,3 event_action=4",
|
| + EXPECT_EQ("InputEvent window=0,3 event_action=4 matched_observer=false",
|
| ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| EXPECT_TRUE(tree1_client->tracker()->changes()->empty());
|
| }
|
| @@ -327,10 +336,117 @@ TEST_F(WindowTreeTest, BasicInputEventTarget) {
|
| ASSERT_EQ(2u, embed_connection->tracker()->changes()->size());
|
| EXPECT_EQ("Focused id=2,1",
|
| ChangesToDescription1(*embed_connection->tracker()->changes())[0]);
|
| - EXPECT_EQ("InputEvent window=2,1 event_action=4",
|
| + EXPECT_EQ("InputEvent window=2,1 event_action=4 matched_observer=false",
|
| ChangesToDescription1(*embed_connection->tracker()->changes())[1]);
|
| }
|
|
|
| +// Tests that a client can observe events outside its bounds.
|
| +TEST_F(WindowTreeTest, SetEventObserver) {
|
| + // Create an embedded client.
|
| + TestWindowTreeClient* client = nullptr;
|
| + WindowTree* tree = nullptr;
|
| + ServerWindow* window = nullptr;
|
| + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
|
| +
|
| + // Create an event outside the bounds of the client.
|
| + ui::PointerEvent pointer_down = CreatePointerDownEvent(5, 5);
|
| +
|
| + // Events are not observed before setting an observer.
|
| + DispatchEventAndAckImmediately(pointer_down);
|
| + ASSERT_EQ(0u, client->tracker()->changes()->size());
|
| +
|
| + // Create an observer for pointer-down events.
|
| + WindowTreeTestApi(tree).SetEventObserver(
|
| + CreateEventMatcher(mojom::EventType::POINTER_DOWN));
|
| +
|
| + // Pointer-down events are sent to the client.
|
| + DispatchEventAndAckImmediately(pointer_down);
|
| + ASSERT_EQ(1u, client->tracker()->changes()->size());
|
| + EXPECT_EQ("EventObserved event_action=4",
|
| + ChangesToDescription1(*client->tracker()->changes())[0]);
|
| + client->tracker()->changes()->clear();
|
| +
|
| + // Clearing the observer stops sending events to the client.
|
| + WindowTreeTestApi(tree).SetEventObserver(nullptr);
|
| + DispatchEventAndAckImmediately(pointer_down);
|
| + ASSERT_EQ(0u, client->tracker()->changes()->size());
|
| +}
|
| +
|
| +// Tests that a client using an event observer does not receive events that
|
| +// don't match the EventMatcher spec.
|
| +TEST_F(WindowTreeTest, SetEventObserverNonMatching) {
|
| + // Create an embedded client.
|
| + TestWindowTreeClient* client = nullptr;
|
| + WindowTree* tree = nullptr;
|
| + ServerWindow* window = nullptr;
|
| + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
|
| +
|
| + // Create an observer for pointer-down events.
|
| + WindowTreeTestApi(tree).SetEventObserver(
|
| + CreateEventMatcher(mojom::EventType::POINTER_DOWN));
|
| +
|
| + // Pointer-up events are not sent to the client, since they don't match.
|
| + DispatchEventAndAckImmediately(CreatePointerUpEvent(5, 5));
|
| + ASSERT_EQ(0u, client->tracker()->changes()->size());
|
| +}
|
| +
|
| +// Tests that an event that both hits a client window and matches an event
|
| +// observer is sent only once to the client.
|
| +TEST_F(WindowTreeTest, SetEventObserverSendsOnce) {
|
| + // Create an embedded client.
|
| + TestWindowTreeClient* client = nullptr;
|
| + WindowTree* tree = nullptr;
|
| + ServerWindow* window = nullptr;
|
| + EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
|
| +
|
| + // Create an observer for pointer-up events (which do not cause focus
|
| + // changes).
|
| + WindowTreeTestApi(tree).SetEventObserver(
|
| + CreateEventMatcher(mojom::EventType::POINTER_UP));
|
| +
|
| + // Create an event inside the bounds of the client.
|
| + ui::PointerEvent pointer_up = CreatePointerUpEvent(25, 25);
|
| +
|
| + // The event is dispatched once, with a flag set that it matched the event
|
| + // observer.
|
| + DispatchEventAndAckImmediately(pointer_up);
|
| + ASSERT_EQ(1u, client->tracker()->changes()->size());
|
| + EXPECT_EQ("InputEvent window=2,1 event_action=6 matched_observer=true",
|
| + SingleChangeToDescription(*client->tracker()->changes()));
|
| +}
|
| +
|
| +// Tests that events generated by user A are not observed by event observers for
|
| +// user B.
|
| +TEST_F(WindowTreeTest, SetEventObserverWrongUser) {
|
| + // Embed a window tree belonging to a different user.
|
| + TestWindowTreeBinding* other_binding;
|
| + WindowTree* other_tree = CreateNewTree("other_user", &other_binding);
|
| + other_binding->client()->tracker()->changes()->clear();
|
| +
|
| + // Set event observers on both the wm tree and the other user's tree.
|
| + WindowTreeTestApi(wm_tree()).SetEventObserver(
|
| + CreateEventMatcher(mojom::EventType::POINTER_UP));
|
| + WindowTreeTestApi(other_tree)
|
| + .SetEventObserver(CreateEventMatcher(mojom::EventType::POINTER_UP));
|
| +
|
| + // An event is observed by the wm tree, but not by the other user's tree.
|
| + DispatchEventAndAckImmediately(CreatePointerUpEvent(5, 5));
|
| + ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
|
| + EXPECT_EQ("InputEvent window=0,3 event_action=6 matched_observer=true",
|
| + SingleChangeToDescription(*wm_client()->tracker()->changes()));
|
| + ASSERT_EQ(0u, other_binding->client()->tracker()->changes()->size());
|
| +}
|
| +
|
| +// Tests that an event observer can receive events that have no target window.
|
| +TEST_F(WindowTreeTest, SetEventObserverNoTarget) {
|
| + WindowTreeTestApi(wm_tree()).SetEventObserver(
|
| + CreateEventMatcher(mojom::EventType::KEY_RELEASED));
|
| + ui::KeyEvent key(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::EF_NONE);
|
| + DispatchEventAndAckImmediately(key);
|
| + EXPECT_EQ("EventObserved event_action=2",
|
| + SingleChangeToDescription(*wm_client()->tracker()->changes()));
|
| +}
|
| +
|
| TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) {
|
| TestWindowTreeClient* embed_connection = nullptr;
|
| WindowTree* tree = nullptr;
|
| @@ -480,7 +596,7 @@ TEST_F(WindowTreeTest, EventAck) {
|
| wm_client()->tracker()->changes()->clear();
|
| DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22));
|
| ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
|
| - EXPECT_EQ("InputEvent window=0,3 event_action=5",
|
| + EXPECT_EQ("InputEvent window=0,3 event_action=5 matched_observer=false",
|
| ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| wm_client()->tracker()->changes()->clear();
|
|
|
| @@ -491,7 +607,7 @@ TEST_F(WindowTreeTest, EventAck) {
|
| // Ack the first event. That should trigger the dispatch of the second event.
|
| AckPreviousEvent();
|
| ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
|
| - EXPECT_EQ("InputEvent window=0,3 event_action=5",
|
| + EXPECT_EQ("InputEvent window=0,3 event_action=5 matched_observer=false",
|
| ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| }
|
|
|
|
|