| 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 6a191b4f838fa5f3abab95d371a95689369a25ed..3e7d486e1215a451f25b2e5ce9ccc7ebedc97544 100644
|
| --- a/components/mus/ws/window_tree_unittest.cc
|
| +++ b/components/mus/ws/window_tree_unittest.cc
|
| @@ -89,6 +89,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
|
|
|
| // -----------------------------------------------------------------------------
|
| @@ -170,6 +177,7 @@ class WindowTreeTest : public testing::Test {
|
| display_binding_ = new TestDisplayBinding(display_, window_server_.get());
|
| display_->Init(base::WrapUnique(display_binding_));
|
| wm_client_ = delegate_.last_client();
|
| + wm_client_->tracker()->changes()->clear();
|
| }
|
|
|
| protected:
|
| @@ -208,6 +216,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));
|
|
|
| @@ -334,6 +343,113 @@ TEST_F(WindowTreeTest, BasicInputEventTarget) {
|
| 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), 111u);
|
| +
|
| + // Pointer-down events are sent to the client.
|
| + DispatchEventAndAckImmediately(pointer_down);
|
| + ASSERT_EQ(1u, client->tracker()->changes()->size());
|
| + EXPECT_EQ("EventObserved event_action=4 event_observer_id=111",
|
| + ChangesToDescription1(*client->tracker()->changes())[0]);
|
| + client->tracker()->changes()->clear();
|
| +
|
| + // Clearing the observer stops sending events to the client.
|
| + WindowTreeTestApi(tree).SetEventObserver(nullptr, 0u);
|
| + 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), 111u);
|
| +
|
| + // 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), 111u);
|
| +
|
| + // 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 event_observer_id=111",
|
| + 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), 111u);
|
| + WindowTreeTestApi(other_tree)
|
| + .SetEventObserver(CreateEventMatcher(mojom::EventType::POINTER_UP), 222u);
|
| +
|
| + // 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 event_observer_id=111",
|
| + 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), 111u);
|
| + ui::KeyEvent key(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::EF_NONE);
|
| + DispatchEventAndAckImmediately(key);
|
| + EXPECT_EQ("EventObserved event_action=2 event_observer_id=111",
|
| + SingleChangeToDescription(*wm_client()->tracker()->changes()));
|
| +}
|
| +
|
| TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) {
|
| TestWindowTreeClient* embed_connection = nullptr;
|
| WindowTree* tree = nullptr;
|
|
|