| 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
|
| deleted file mode 100644
|
| index 15356763085d5929475e46c94cbdb80d2a45352c..0000000000000000000000000000000000000000
|
| --- a/components/mus/ws/window_tree_unittest.cc
|
| +++ /dev/null
|
| @@ -1,1017 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "components/mus/ws/window_tree.h"
|
| -
|
| -#include <stdint.h>
|
| -
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/macros.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "components/mus/common/types.h"
|
| -#include "components/mus/common/util.h"
|
| -#include "components/mus/public/interfaces/window_tree.mojom.h"
|
| -#include "components/mus/surfaces/surfaces_state.h"
|
| -#include "components/mus/ws/default_access_policy.h"
|
| -#include "components/mus/ws/display_binding.h"
|
| -#include "components/mus/ws/ids.h"
|
| -#include "components/mus/ws/platform_display.h"
|
| -#include "components/mus/ws/platform_display_factory.h"
|
| -#include "components/mus/ws/platform_display_init_params.h"
|
| -#include "components/mus/ws/server_window.h"
|
| -#include "components/mus/ws/server_window_surface_manager_test_api.h"
|
| -#include "components/mus/ws/test_change_tracker.h"
|
| -#include "components/mus/ws/test_server_window_delegate.h"
|
| -#include "components/mus/ws/test_utils.h"
|
| -#include "components/mus/ws/window_manager_access_policy.h"
|
| -#include "components/mus/ws/window_manager_display_root.h"
|
| -#include "components/mus/ws/window_server.h"
|
| -#include "components/mus/ws/window_server_delegate.h"
|
| -#include "components/mus/ws/window_tree_binding.h"
|
| -#include "services/shell/public/interfaces/connector.mojom.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "ui/events/event.h"
|
| -#include "ui/events/event_utils.h"
|
| -#include "ui/gfx/geometry/rect.h"
|
| -
|
| -namespace mus {
|
| -namespace ws {
|
| -namespace test {
|
| -namespace {
|
| -
|
| -std::string WindowIdToString(const WindowId& id) {
|
| - return base::StringPrintf("%d,%d", id.client_id, id.window_id);
|
| -}
|
| -
|
| -ClientWindowId BuildClientWindowId(WindowTree* tree,
|
| - ClientSpecificId window_id) {
|
| - return ClientWindowId(WindowIdToTransportId(WindowId(tree->id(), window_id)));
|
| -}
|
| -
|
| -// -----------------------------------------------------------------------------
|
| -
|
| -ui::PointerEvent CreatePointerDownEvent(int x, int y) {
|
| - return ui::PointerEvent(ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(x, y),
|
| - 1, ui::EventTimeForNow()));
|
| -}
|
| -
|
| -ui::PointerEvent CreatePointerUpEvent(int x, int y) {
|
| - return ui::PointerEvent(ui::TouchEvent(
|
| - ui::ET_TOUCH_RELEASED, gfx::Point(x, y), 1, ui::EventTimeForNow()));
|
| -}
|
| -
|
| -ui::PointerEvent CreateMouseMoveEvent(int x, int y) {
|
| - return ui::PointerEvent(
|
| - ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(x, y), gfx::Point(x, y),
|
| - ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE));
|
| -}
|
| -
|
| -ui::PointerEvent CreateMouseDownEvent(int x, int y) {
|
| - return ui::PointerEvent(
|
| - ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(x, y), gfx::Point(x, y),
|
| - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
|
| - ui::EF_LEFT_MOUSE_BUTTON));
|
| -}
|
| -
|
| -ui::PointerEvent CreateMouseUpEvent(int x, int y) {
|
| - return ui::PointerEvent(
|
| - ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(x, y), gfx::Point(x, y),
|
| - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
|
| - ui::EF_LEFT_MOUSE_BUTTON));
|
| -}
|
| -
|
| -ServerWindow* GetCaptureWindow(Display* display) {
|
| - return display->GetActiveWindowManagerDisplayRoot()
|
| - ->window_manager_state()
|
| - ->capture_window();
|
| -}
|
| -
|
| -mojom::EventMatcherPtr CreateEventMatcher(ui::mojom::EventType type) {
|
| - mojom::EventMatcherPtr matcher = mojom::EventMatcher::New();
|
| - matcher->type_matcher = mojom::EventTypeMatcher::New();
|
| - matcher->type_matcher->type = type;
|
| - return matcher;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// -----------------------------------------------------------------------------
|
| -
|
| -class WindowTreeTest : public testing::Test {
|
| - public:
|
| - WindowTreeTest() {}
|
| - ~WindowTreeTest() override {}
|
| -
|
| - mus::mojom::Cursor cursor_id() {
|
| - return static_cast<mus::mojom::Cursor>(
|
| - window_event_targeting_helper_.cursor_id());
|
| - }
|
| - Display* display() { return window_event_targeting_helper_.display(); }
|
| - TestWindowTreeBinding* last_binding() {
|
| - return window_event_targeting_helper_.last_binding();
|
| - }
|
| - TestWindowTreeClient* last_window_tree_client() {
|
| - return window_event_targeting_helper_.last_window_tree_client();
|
| - }
|
| - TestWindowTreeClient* wm_client() {
|
| - return window_event_targeting_helper_.wm_client();
|
| - }
|
| - WindowServer* window_server() {
|
| - return window_event_targeting_helper_.window_server();
|
| - }
|
| - WindowTree* wm_tree() {
|
| - return window_event_targeting_helper_.window_server()->GetTreeWithId(1);
|
| - }
|
| -
|
| - void DispatchEventWithoutAck(const ui::Event& event) {
|
| - DisplayTestApi(display()).OnEvent(event);
|
| - }
|
| -
|
| - void set_window_manager_internal(WindowTree* tree,
|
| - mojom::WindowManager* wm_internal) {
|
| - WindowTreeTestApi(tree).set_window_manager_internal(wm_internal);
|
| - }
|
| -
|
| - void AckPreviousEvent() {
|
| - WindowManagerStateTestApi test_api(
|
| - display()->GetActiveWindowManagerDisplayRoot()->window_manager_state());
|
| - while (test_api.tree_awaiting_input_ack()) {
|
| - test_api.tree_awaiting_input_ack()->OnWindowInputEventAck(
|
| - 0, mojom::EventResult::HANDLED);
|
| - }
|
| - }
|
| -
|
| - void DispatchEventAndAckImmediately(const ui::Event& event) {
|
| - DispatchEventWithoutAck(event);
|
| - AckPreviousEvent();
|
| - }
|
| -
|
| - // Creates a new window from wm_tree() and embeds a new client in it.
|
| - void SetupEventTargeting(TestWindowTreeClient** out_client,
|
| - WindowTree** window_tree,
|
| - ServerWindow** window);
|
| -
|
| - // Creates a new tree as the specified user. This does what creation via
|
| - // a WindowTreeFactory does.
|
| - WindowTree* CreateNewTree(const UserId& user_id,
|
| - TestWindowTreeBinding** binding) {
|
| - WindowTree* tree =
|
| - new WindowTree(window_server(), user_id, nullptr,
|
| - base::WrapUnique(new DefaultAccessPolicy));
|
| - *binding = new TestWindowTreeBinding(tree);
|
| - window_server()->AddTree(base::WrapUnique(tree), base::WrapUnique(*binding),
|
| - nullptr);
|
| - return tree;
|
| - }
|
| -
|
| - protected:
|
| - WindowEventTargetingHelper window_event_targeting_helper_;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(WindowTreeTest);
|
| -};
|
| -
|
| -// Creates a new window in wm_tree(), adds it to the root, embeds a
|
| -// new client in the window and creates a child of said window. |window| is
|
| -// set to the child of |window_tree| that is created.
|
| -void WindowTreeTest::SetupEventTargeting(TestWindowTreeClient** out_client,
|
| - WindowTree** window_tree,
|
| - ServerWindow** window) {
|
| - ServerWindow* embed_window = window_event_targeting_helper_.CreatePrimaryTree(
|
| - gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 50, 50));
|
| - window_event_targeting_helper_.CreateSecondaryTree(
|
| - embed_window, gfx::Rect(20, 20, 20, 20), out_client, window_tree, window);
|
| -}
|
| -
|
| -// Verifies focus correctly changes on pointer events.
|
| -TEST_F(WindowTreeTest, FocusOnPointer) {
|
| - const ClientWindowId embed_window_id = BuildClientWindowId(wm_tree(), 1);
|
| - EXPECT_TRUE(
|
| - wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties()));
|
| - ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id);
|
| - ASSERT_TRUE(embed_window);
|
| - EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id, true));
|
| - ASSERT_TRUE(FirstRoot(wm_tree()));
|
| - const ClientWindowId wm_root_id = FirstRootId(wm_tree());
|
| - EXPECT_TRUE(wm_tree()->AddWindow(wm_root_id, embed_window_id));
|
| - display()->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - mojom::WindowTreeClientPtr client;
|
| - mojom::WindowTreeClientRequest client_request = GetProxy(&client);
|
| - wm_client()->Bind(std::move(client_request));
|
| - const uint32_t embed_flags = 0;
|
| - wm_tree()->Embed(embed_window_id, std::move(client), embed_flags);
|
| - WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window);
|
| - ASSERT_TRUE(tree1 != nullptr);
|
| - ASSERT_NE(tree1, wm_tree());
|
| -
|
| - embed_window->SetBounds(gfx::Rect(0, 0, 50, 50));
|
| -
|
| - const ClientWindowId child1_id(BuildClientWindowId(tree1, 1));
|
| - EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties()));
|
| - EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window),
|
| - child1_id));
|
| - ServerWindow* child1 = tree1->GetWindowByClientId(child1_id);
|
| - ASSERT_TRUE(child1);
|
| - child1->SetVisible(true);
|
| - child1->SetBounds(gfx::Rect(20, 20, 20, 20));
|
| - EnableHitTest(child1);
|
| -
|
| - TestWindowTreeClient* tree1_client = last_window_tree_client();
|
| - tree1_client->tracker()->changes()->clear();
|
| - wm_client()->tracker()->changes()->clear();
|
| -
|
| - // Focus should not go to |child1| yet, since the parent still doesn't allow
|
| - // active children.
|
| - DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22));
|
| - Display* display1 = tree1->GetDisplay(embed_window);
|
| - EXPECT_EQ(nullptr, display1->GetFocusedWindow());
|
| - DispatchEventAndAckImmediately(CreatePointerUpEvent(21, 22));
|
| - tree1_client->tracker()->changes()->clear();
|
| - wm_client()->tracker()->changes()->clear();
|
| -
|
| - display1->AddActivationParent(embed_window);
|
| -
|
| - // Focus should go to child1. This result in notifying both the window
|
| - // manager and client client being notified.
|
| - DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22));
|
| - EXPECT_EQ(child1, display1->GetFocusedWindow());
|
| - ASSERT_GE(wm_client()->tracker()->changes()->size(), 1u);
|
| - EXPECT_EQ("Focused id=2,1",
|
| - ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| - ASSERT_GE(tree1_client->tracker()->changes()->size(), 1u);
|
| - EXPECT_EQ("Focused id=2,1",
|
| - ChangesToDescription1(*tree1_client->tracker()->changes())[0]);
|
| -
|
| - DispatchEventAndAckImmediately(CreatePointerUpEvent(21, 22));
|
| - wm_client()->tracker()->changes()->clear();
|
| - tree1_client->tracker()->changes()->clear();
|
| -
|
| - // Press outside of the embedded window. Note that root cannot be focused
|
| - // (because it cannot be activated). So the focus would not move in this case.
|
| - DispatchEventAndAckImmediately(CreatePointerDownEvent(61, 22));
|
| - EXPECT_EQ(child1, display()->GetFocusedWindow());
|
| -
|
| - DispatchEventAndAckImmediately(CreatePointerUpEvent(21, 22));
|
| - wm_client()->tracker()->changes()->clear();
|
| - tree1_client->tracker()->changes()->clear();
|
| -
|
| - // Press in the same location. Should not get a focus change event (only input
|
| - // event).
|
| - DispatchEventAndAckImmediately(CreatePointerDownEvent(61, 22));
|
| - 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=16",
|
| - ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| - EXPECT_TRUE(tree1_client->tracker()->changes()->empty());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, BasicInputEventTarget) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(
|
| - SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - // Send an event to |v1|. |embed_client| should get the event, not
|
| - // |wm_client|, since |v1| lives inside an embedded window.
|
| - DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22));
|
| - ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
|
| - EXPECT_EQ("Focused id=2,1",
|
| - ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| - ASSERT_EQ(2u, embed_client->tracker()->changes()->size());
|
| - EXPECT_EQ("Focused id=2,1",
|
| - ChangesToDescription1(*embed_client->tracker()->changes())[0]);
|
| - EXPECT_EQ("InputEvent window=2,1 event_action=16",
|
| - ChangesToDescription1(*embed_client->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(ui::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=16 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(ui::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(ui::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=18 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(ui::mojom::EventType::POINTER_UP), 111u);
|
| - WindowTreeTestApi(other_tree)
|
| - .SetEventObserver(CreateEventMatcher(ui::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=18 event_observer_id=111",
|
| - SingleChangeToDescription(*wm_client()->tracker()->changes()));
|
| - ASSERT_EQ(0u, other_binding->client()->tracker()->changes()->size());
|
| -}
|
| -
|
| -// Tests that an event observer cannot observe keystrokes.
|
| -TEST_F(WindowTreeTest, SetEventObserverKeyEventsDisallowed) {
|
| - WindowTreeTestApi(wm_tree()).SetEventObserver(
|
| - CreateEventMatcher(ui::mojom::EventType::KEY_PRESSED), 111u);
|
| - ui::KeyEvent key_pressed(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
|
| - DispatchEventAndAckImmediately(key_pressed);
|
| - EXPECT_EQ(0u, wm_client()->tracker()->changes()->size());
|
| -
|
| - WindowTreeTestApi(wm_tree()).SetEventObserver(
|
| - CreateEventMatcher(ui::mojom::EventType::KEY_RELEASED), 222u);
|
| - ui::KeyEvent key_released(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::EF_NONE);
|
| - DispatchEventAndAckImmediately(key_released);
|
| - EXPECT_EQ(0u, wm_client()->tracker()->changes()->size());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - // Like in BasicInputEventTarget, we send a pointer down event to be
|
| - // dispatched. This is only to place the mouse cursor over that window though.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
|
| -
|
| - window->SetPredefinedCursor(mojom::Cursor::IBEAM);
|
| -
|
| - // Because the cursor is over the window when SetCursor was called, we should
|
| - // have immediately changed the cursor.
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, CursorChangesWhenEnteringWindowWithDifferentCursor) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - // Let's create a pointer event outside the window and then move the pointer
|
| - // inside.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
|
| - window->SetPredefinedCursor(mojom::Cursor::IBEAM);
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, TouchesDontChangeCursor) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - // Let's create a pointer event outside the window and then move the pointer
|
| - // inside.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
|
| - window->SetPredefinedCursor(mojom::Cursor::IBEAM);
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -
|
| - // With a touch event, we shouldn't update the cursor.
|
| - DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22));
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, DragOutsideWindow) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - // Start with the cursor outside the window. Setting the cursor shouldn't
|
| - // change the cursor.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
|
| - window->SetPredefinedCursor(mojom::Cursor::IBEAM);
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -
|
| - // Move the pointer to the inside of the window
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -
|
| - // Start the drag.
|
| - DispatchEventAndAckImmediately(CreateMouseDownEvent(21, 22));
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -
|
| - // Move the cursor (mouse is still down) outside the window.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -
|
| - // Release the cursor. We should now adapt the cursor of the window
|
| - // underneath the pointer.
|
| - DispatchEventAndAckImmediately(CreateMouseUpEvent(5, 5));
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, ChangingWindowBoundsChangesCursor) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - // Put the cursor just outside the bounds of the window.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(41, 41));
|
| - window->SetPredefinedCursor(mojom::Cursor::IBEAM);
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -
|
| - // Expand the bounds of the window so they now include where the cursor now
|
| - // is.
|
| - window->SetBounds(gfx::Rect(20, 20, 25, 25));
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -
|
| - // Contract the bounds again.
|
| - window->SetBounds(gfx::Rect(20, 20, 20, 20));
|
| - EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, WindowReorderingChangesCursor) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window1));
|
| -
|
| - // Create a second window right over the first.
|
| - const ClientWindowId embed_window_id(FirstRootId(tree));
|
| - const ClientWindowId child2_id(BuildClientWindowId(tree, 2));
|
| - EXPECT_TRUE(tree->NewWindow(child2_id, ServerWindow::Properties()));
|
| - ServerWindow* child2 = tree->GetWindowByClientId(child2_id);
|
| - ASSERT_TRUE(child2);
|
| - EXPECT_TRUE(tree->AddWindow(embed_window_id, child2_id));
|
| - child2->SetVisible(true);
|
| - child2->SetBounds(gfx::Rect(20, 20, 20, 20));
|
| - EnableHitTest(child2);
|
| -
|
| - // Give each window a different cursor.
|
| - window1->SetPredefinedCursor(mojom::Cursor::IBEAM);
|
| - child2->SetPredefinedCursor(mojom::Cursor::HAND);
|
| -
|
| - // We expect window2 to be over window1 now.
|
| - DispatchEventAndAckImmediately(CreateMouseMoveEvent(22, 22));
|
| - EXPECT_EQ(mojom::Cursor::HAND, cursor_id());
|
| -
|
| - // But when we put window2 at the bottom, we should adapt window1's cursor.
|
| - child2->parent()->StackChildAtBottom(child2);
|
| - EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, EventAck) {
|
| - const ClientWindowId embed_window_id = BuildClientWindowId(wm_tree(), 1);
|
| - EXPECT_TRUE(
|
| - wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties()));
|
| - EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id, true));
|
| - ASSERT_TRUE(FirstRoot(wm_tree()));
|
| - EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id));
|
| - display()->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| -
|
| - 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=17",
|
| - ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| - wm_client()->tracker()->changes()->clear();
|
| -
|
| - // Send another event. This event shouldn't reach the client.
|
| - DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22));
|
| - ASSERT_EQ(0u, wm_client()->tracker()->changes()->size());
|
| -
|
| - // 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=17",
|
| - ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
|
| -}
|
| -
|
| -// Establish client, call NewTopLevelWindow(), make sure get id, and make
|
| -// sure client paused.
|
| -TEST_F(WindowTreeTest, NewTopLevelWindow) {
|
| - TestWindowManager wm_internal;
|
| - set_window_manager_internal(wm_tree(), &wm_internal);
|
| -
|
| - TestWindowTreeBinding* child_binding;
|
| - WindowTree* child_tree = CreateNewTree(wm_tree()->user_id(), &child_binding);
|
| - child_binding->client()->tracker()->changes()->clear();
|
| - child_binding->client()->set_record_on_change_completed(true);
|
| -
|
| - // Create a new top level window.
|
| - mojo::Map<mojo::String, mojo::Array<uint8_t>> properties;
|
| - const uint32_t initial_change_id = 17;
|
| - // Explicitly use an id that does not contain the client id.
|
| - const ClientWindowId embed_window_id2_in_child(45 << 16 | 27);
|
| - static_cast<mojom::WindowTree*>(child_tree)
|
| - ->NewTopLevelWindow(initial_change_id, embed_window_id2_in_child.id,
|
| - std::move(properties));
|
| -
|
| - // The binding should be paused until the wm acks the change.
|
| - uint32_t wm_change_id = 0u;
|
| - ASSERT_TRUE(wm_internal.did_call_create_top_level_window(&wm_change_id));
|
| - EXPECT_TRUE(child_binding->is_paused());
|
| -
|
| - // Create the window for |embed_window_id2_in_child|.
|
| - const ClientWindowId embed_window_id2 = BuildClientWindowId(wm_tree(), 2);
|
| - EXPECT_TRUE(
|
| - wm_tree()->NewWindow(embed_window_id2, ServerWindow::Properties()));
|
| - EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id2, true));
|
| - EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id2));
|
| -
|
| - // Ack the change, which should resume the binding.
|
| - child_binding->client()->tracker()->changes()->clear();
|
| - static_cast<mojom::WindowManagerClient*>(wm_tree())
|
| - ->OnWmCreatedTopLevelWindow(wm_change_id, embed_window_id2.id);
|
| - EXPECT_FALSE(child_binding->is_paused());
|
| - EXPECT_EQ("TopLevelCreated id=17 window_id=" +
|
| - WindowIdToString(
|
| - WindowIdFromTransportId(embed_window_id2_in_child.id)) +
|
| - " drawn=true",
|
| - SingleChangeToDescription(
|
| - *child_binding->client()->tracker()->changes()));
|
| - child_binding->client()->tracker()->changes()->clear();
|
| -
|
| - // Change the visibility of the window from the owner and make sure the
|
| - // client sees the right id.
|
| - ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id2);
|
| - ASSERT_TRUE(embed_window);
|
| - EXPECT_TRUE(embed_window->visible());
|
| - ASSERT_TRUE(wm_tree()->SetWindowVisibility(
|
| - ClientWindowIdForWindow(wm_tree(), embed_window), false));
|
| - EXPECT_FALSE(embed_window->visible());
|
| - EXPECT_EQ("VisibilityChanged window=" +
|
| - WindowIdToString(
|
| - WindowIdFromTransportId(embed_window_id2_in_child.id)) +
|
| - " visible=false",
|
| - SingleChangeToDescription(
|
| - *child_binding->client()->tracker()->changes()));
|
| -
|
| - // Set the visibility from the child using the client assigned id.
|
| - ASSERT_TRUE(child_tree->SetWindowVisibility(embed_window_id2_in_child, true));
|
| - EXPECT_TRUE(embed_window->visible());
|
| -}
|
| -
|
| -// Tests that only the capture window can release capture.
|
| -TEST_F(WindowTreeTest, ExplicitSetCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - tree->AddWindow(FirstRootId(tree), ClientWindowIdForWindow(tree, window));
|
| - window->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - ASSERT_TRUE(tree->GetDisplay(window));
|
| -
|
| - // Set capture.
|
| - mojom::WindowTree* mojom_window_tree = static_cast<mojom::WindowTree*>(tree);
|
| - uint32_t change_id = 42;
|
| - mojom_window_tree->SetCapture(change_id, WindowIdToTransportId(window->id()));
|
| - Display* display = tree->GetDisplay(window);
|
| - EXPECT_EQ(window, GetCaptureWindow(display));
|
| -
|
| - // Only the capture window should be able to release capture
|
| - mojom_window_tree->ReleaseCapture(++change_id,
|
| - WindowIdToTransportId(root_window->id()));
|
| - EXPECT_EQ(window, GetCaptureWindow(display));
|
| - mojom_window_tree->ReleaseCapture(++change_id,
|
| - WindowIdToTransportId(window->id()));
|
| - EXPECT_EQ(nullptr, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that while a client is interacting with input, that capture is not
|
| -// allowed for invisible windows.
|
| -TEST_F(WindowTreeTest, CaptureWindowMustBeVisible) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| - tree->AddWindow(FirstRootId(tree), ClientWindowIdForWindow(tree, window));
|
| - window->SetBounds(gfx::Rect(0, 0, 100, 100));
|
| - ASSERT_TRUE(tree->GetDisplay(window));
|
| -
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(10, 10));
|
| - window->SetVisible(false);
|
| - EXPECT_FALSE(tree->SetCapture(ClientWindowIdForWindow(tree, window)));
|
| - EXPECT_NE(window, GetCaptureWindow(tree->GetDisplay(window)));
|
| -}
|
| -
|
| -// Tests that showing a modal window releases the capture if the capture is on a
|
| -// descendant of the modal parent.
|
| -TEST_F(WindowTreeTest, ShowModalWindowWithDescendantCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 30, 30));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create |w11| as a child of |w1| and make it visible.
|
| - ClientWindowId w11_id = BuildClientWindowId(tree, 11);
|
| - ASSERT_TRUE(tree->NewWindow(w11_id, ServerWindow::Properties()));
|
| - ServerWindow* w11 = tree->GetWindowByClientId(w11_id);
|
| - w11->SetBounds(gfx::Rect(10, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(w1_id, w11_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w11_id, true));
|
| -
|
| - // Create |w2| as a child of |root_window| and modal to |w1| and leave it
|
| - // hidden.
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(50, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->AddTransientWindow(w1_id, w2_id));
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| -
|
| - // Set capture to |w11|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(25, 25));
|
| - ASSERT_TRUE(tree->SetCapture(w11_id));
|
| - EXPECT_EQ(w11, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Make |w2| visible. This should release capture as capture is set to a
|
| - // descendant of the modal parent.
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| - EXPECT_EQ(nullptr, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that setting a visible window as modal releases the capture if the
|
| -// capture is on a descendant of the modal parent.
|
| -TEST_F(WindowTreeTest, VisibleWindowToModalWithDescendantCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 30, 30));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create |w11| as a child of |w1| and make it visible.
|
| - ClientWindowId w11_id = BuildClientWindowId(tree, 11);
|
| - ASSERT_TRUE(tree->NewWindow(w11_id, ServerWindow::Properties()));
|
| - ServerWindow* w11 = tree->GetWindowByClientId(w11_id);
|
| - w11->SetBounds(gfx::Rect(10, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(w1_id, w11_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w11_id, true));
|
| -
|
| - // Create |w2| as a child of |root_window| and make it visible.
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(50, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| -
|
| - // Set capture to |w11|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(25, 25));
|
| - ASSERT_TRUE(tree->SetCapture(w11_id));
|
| - EXPECT_EQ(w11, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Set |w2| modal to |w1|. This should release the capture as the capture is
|
| - // set to a descendant of the modal parent.
|
| - ASSERT_TRUE(tree->AddTransientWindow(w1_id, w2_id));
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| - EXPECT_EQ(nullptr, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that showing a modal window does not change capture if the capture is
|
| -// not on a descendant of the modal parent.
|
| -TEST_F(WindowTreeTest, ShowModalWindowWithNonDescendantCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 30, 30));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create |w2| as a child of |root_window| and modal to |w1| and leave it
|
| - // hidden..
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(50, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->AddTransientWindow(w1_id, w2_id));
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| -
|
| - // Create |w3| as a child of |root_window| and make it visible.
|
| - ClientWindowId w3_id = BuildClientWindowId(tree, 3);
|
| - ASSERT_TRUE(tree->NewWindow(w3_id, ServerWindow::Properties()));
|
| - ServerWindow* w3 = tree->GetWindowByClientId(w3_id);
|
| - w3->SetBounds(gfx::Rect(70, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w3_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w3_id, true));
|
| -
|
| - // Set capture to |w3|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(25, 25));
|
| - ASSERT_TRUE(tree->SetCapture(w3_id));
|
| - EXPECT_EQ(w3, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Make |w2| visible. This should not change the capture as the capture is not
|
| - // set to a descendant of the modal parent.
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| - EXPECT_EQ(w3, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that setting a visible window as modal does not change the capture if
|
| -// the capture is not set to a descendant of the modal parent.
|
| -TEST_F(WindowTreeTest, VisibleWindowToModalWithNonDescendantCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 30, 30));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create |w2| and |w3| as children of |root_window| and make them visible.
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(50, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| -
|
| - ClientWindowId w3_id = BuildClientWindowId(tree, 3);
|
| - ASSERT_TRUE(tree->NewWindow(w3_id, ServerWindow::Properties()));
|
| - ServerWindow* w3 = tree->GetWindowByClientId(w3_id);
|
| - w3->SetBounds(gfx::Rect(70, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w3_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w3_id, true));
|
| -
|
| - // Set capture to |w3|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(25, 25));
|
| - ASSERT_TRUE(tree->SetCapture(w3_id));
|
| - EXPECT_EQ(w3, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Set |w2| modal to |w1|. This should not release the capture as the capture
|
| - // is not set to a descendant of the modal parent.
|
| - ASSERT_TRUE(tree->AddTransientWindow(w1_id, w2_id));
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| - EXPECT_EQ(w3, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that showing a system modal window releases the capture.
|
| -TEST_F(WindowTreeTest, ShowSystemModalWindowWithCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 10, 10));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create a system modal window |w2| as a child of |root_window| and leave it
|
| - // hidden.
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(30, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| -
|
| - // Set capture to |w1|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(15, 15));
|
| - ASSERT_TRUE(tree->SetCapture(w1_id));
|
| - EXPECT_EQ(w1, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Make |w2| visible. This should release capture as it is system modal
|
| - // window.
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| - EXPECT_EQ(nullptr, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that setting a visible window as modal to system releases the capture.
|
| -TEST_F(WindowTreeTest, VisibleWindowToSystemModalWithCapture) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 10, 10));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create |w2| as a child of |root_window| and make it visible.
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(30, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| -
|
| - // Set capture to |w1|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(15, 15));
|
| - ASSERT_TRUE(tree->SetCapture(w1_id));
|
| - EXPECT_EQ(w1, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Make |w2| modal to system. This should release capture.
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| - EXPECT_EQ(nullptr, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that moving the capture window to a modal parent releases the capture
|
| -// as capture cannot be blocked by a modal window.
|
| -TEST_F(WindowTreeTest, MoveCaptureWindowToModalParent) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* w1 = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &w1));
|
| -
|
| - w1->SetBounds(gfx::Rect(10, 10, 30, 30));
|
| - const ServerWindow* root_window = *tree->roots().begin();
|
| - ClientWindowId root_window_id = ClientWindowIdForWindow(tree, root_window);
|
| - ClientWindowId w1_id = ClientWindowIdForWindow(tree, w1);
|
| - Display* display = tree->GetDisplay(w1);
|
| -
|
| - // Create |w2| and |w3| as children of |root_window| and make them visible.
|
| - ClientWindowId w2_id = BuildClientWindowId(tree, 2);
|
| - ASSERT_TRUE(tree->NewWindow(w2_id, ServerWindow::Properties()));
|
| - ServerWindow* w2 = tree->GetWindowByClientId(w2_id);
|
| - w2->SetBounds(gfx::Rect(50, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w2_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w2_id, true));
|
| -
|
| - ClientWindowId w3_id = BuildClientWindowId(tree, 3);
|
| - ASSERT_TRUE(tree->NewWindow(w3_id, ServerWindow::Properties()));
|
| - ServerWindow* w3 = tree->GetWindowByClientId(w3_id);
|
| - w3->SetBounds(gfx::Rect(70, 10, 10, 10));
|
| - ASSERT_TRUE(tree->AddWindow(root_window_id, w3_id));
|
| - ASSERT_TRUE(tree->SetWindowVisibility(w3_id, true));
|
| -
|
| - // Set |w2| modal to |w1|.
|
| - ASSERT_TRUE(tree->AddTransientWindow(w1_id, w2_id));
|
| - ASSERT_TRUE(tree->SetModal(w2_id));
|
| -
|
| - // Set capture to |w3|.
|
| - DispatchEventWithoutAck(CreatePointerDownEvent(25, 25));
|
| - ASSERT_TRUE(tree->SetCapture(w3_id));
|
| - EXPECT_EQ(w3, GetCaptureWindow(display));
|
| - AckPreviousEvent();
|
| -
|
| - // Make |w3| child of |w1|. This should release capture as |w3| is now blocked
|
| - // by a modal window.
|
| - ASSERT_TRUE(tree->AddWindow(w1_id, w3_id));
|
| - EXPECT_EQ(nullptr, GetCaptureWindow(display));
|
| -}
|
| -
|
| -// Tests that opacity can be set on a known window.
|
| -TEST_F(WindowTreeTest, SetOpacity) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - const float new_opacity = 0.5f;
|
| - EXPECT_NE(new_opacity, window->opacity());
|
| - ASSERT_TRUE(tree->SetWindowOpacity(ClientWindowIdForWindow(tree, window),
|
| - new_opacity));
|
| - EXPECT_EQ(new_opacity, window->opacity());
|
| -
|
| - // Re-applying the same opacity will succeed.
|
| - EXPECT_TRUE(tree->SetWindowOpacity(ClientWindowIdForWindow(tree, window),
|
| - new_opacity));
|
| -}
|
| -
|
| -// Tests that opacity requests for unknown windows are rejected.
|
| -TEST_F(WindowTreeTest, SetOpacityFailsOnUnknownWindow) {
|
| - TestWindowTreeClient* embed_client = nullptr;
|
| - WindowTree* tree = nullptr;
|
| - ServerWindow* window = nullptr;
|
| - EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
|
| -
|
| - TestServerWindowDelegate delegate;
|
| - WindowId window_id(42, 1337);
|
| - ServerWindow unknown_window(&delegate, window_id);
|
| - const float new_opacity = 0.5f;
|
| - ASSERT_NE(new_opacity, unknown_window.opacity());
|
| -
|
| - EXPECT_FALSE(tree->SetWindowOpacity(
|
| - ClientWindowId(WindowIdToTransportId(window_id)), new_opacity));
|
| - EXPECT_NE(new_opacity, unknown_window.opacity());
|
| -}
|
| -
|
| -TEST_F(WindowTreeTest, SetCaptureTargetsRightConnection) {
|
| - ServerWindow* window = window_event_targeting_helper_.CreatePrimaryTree(
|
| - gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 50, 50));
|
| - WindowTree* owning_tree =
|
| - window_server()->GetTreeWithId(window->id().client_id);
|
| - WindowTree* embed_tree = window_server()->GetTreeWithRoot(window);
|
| - ASSERT_NE(owning_tree, embed_tree);
|
| - ASSERT_TRUE(
|
| - owning_tree->SetCapture(ClientWindowIdForWindow(owning_tree, window)));
|
| - DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22));
|
| - WindowManagerStateTestApi wm_state_test_api(
|
| - display()->GetActiveWindowManagerDisplayRoot()->window_manager_state());
|
| - EXPECT_EQ(owning_tree, wm_state_test_api.tree_awaiting_input_ack());
|
| - AckPreviousEvent();
|
| -
|
| - // Set capture from the embedded client and make sure it gets the event.
|
| - ASSERT_TRUE(
|
| - embed_tree->SetCapture(ClientWindowIdForWindow(embed_tree, window)));
|
| - DispatchEventWithoutAck(CreateMouseMoveEvent(22, 23));
|
| - EXPECT_EQ(embed_tree, wm_state_test_api.tree_awaiting_input_ack());
|
| -}
|
| -
|
| -} // namespace test
|
| -} // namespace ws
|
| -} // namespace mus
|
|
|