| Index: components/mus/ws/window_tree.cc
|
| diff --git a/components/mus/ws/window_tree.cc b/components/mus/ws/window_tree.cc
|
| deleted file mode 100644
|
| index aafdfce96ecf04c4fb68d4764078d7186609f6a8..0000000000000000000000000000000000000000
|
| --- a/components/mus/ws/window_tree.cc
|
| +++ /dev/null
|
| @@ -1,1539 +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 <stddef.h>
|
| -
|
| -#include <utility>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/macros.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "base/stl_util.h"
|
| -#include "components/mus/ws/default_access_policy.h"
|
| -#include "components/mus/ws/display.h"
|
| -#include "components/mus/ws/display_manager.h"
|
| -#include "components/mus/ws/event_matcher.h"
|
| -#include "components/mus/ws/focus_controller.h"
|
| -#include "components/mus/ws/operation.h"
|
| -#include "components/mus/ws/platform_display.h"
|
| -#include "components/mus/ws/server_window.h"
|
| -#include "components/mus/ws/server_window_observer.h"
|
| -#include "components/mus/ws/user_display_manager.h"
|
| -#include "components/mus/ws/window_manager_display_root.h"
|
| -#include "components/mus/ws/window_manager_state.h"
|
| -#include "components/mus/ws/window_server.h"
|
| -#include "components/mus/ws/window_tree_binding.h"
|
| -#include "ui/display/display.h"
|
| -#include "ui/platform_window/mojo/ime_type_converters.h"
|
| -#include "ui/platform_window/text_input_state.h"
|
| -
|
| -using mojo::Array;
|
| -using mojo::InterfaceRequest;
|
| -using mojo::String;
|
| -
|
| -namespace mus {
|
| -namespace ws {
|
| -
|
| -class TargetedEvent : public ServerWindowObserver {
|
| - public:
|
| - TargetedEvent(ServerWindow* target, const ui::Event& event)
|
| - : target_(target), event_(ui::Event::Clone(event)) {
|
| - target_->AddObserver(this);
|
| - }
|
| - ~TargetedEvent() override {
|
| - if (target_)
|
| - target_->RemoveObserver(this);
|
| - }
|
| -
|
| - ServerWindow* target() { return target_; }
|
| - std::unique_ptr<ui::Event> TakeEvent() { return std::move(event_); }
|
| -
|
| - private:
|
| - // ServerWindowObserver:
|
| - void OnWindowDestroyed(ServerWindow* window) override {
|
| - DCHECK_EQ(target_, window);
|
| - target_->RemoveObserver(this);
|
| - target_ = nullptr;
|
| - }
|
| -
|
| - ServerWindow* target_;
|
| - std::unique_ptr<ui::Event> event_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TargetedEvent);
|
| -};
|
| -
|
| -WindowTree::WindowTree(WindowServer* window_server,
|
| - const UserId& user_id,
|
| - ServerWindow* root,
|
| - std::unique_ptr<AccessPolicy> access_policy)
|
| - : window_server_(window_server),
|
| - user_id_(user_id),
|
| - id_(window_server_->GetAndAdvanceNextClientId()),
|
| - next_window_id_(1),
|
| - access_policy_(std::move(access_policy)),
|
| - event_ack_id_(0),
|
| - window_manager_internal_(nullptr) {
|
| - if (root)
|
| - roots_.insert(root);
|
| - access_policy_->Init(id_, this);
|
| -}
|
| -
|
| -WindowTree::~WindowTree() {
|
| - DestroyWindows();
|
| -}
|
| -
|
| -void WindowTree::Init(std::unique_ptr<WindowTreeBinding> binding,
|
| - mojom::WindowTreePtr tree) {
|
| - DCHECK(!binding_);
|
| - binding_ = std::move(binding);
|
| -
|
| - if (roots_.empty())
|
| - return;
|
| -
|
| - std::vector<const ServerWindow*> to_send;
|
| - CHECK_EQ(1u, roots_.size());
|
| - const ServerWindow* root = *roots_.begin();
|
| - GetUnknownWindowsFrom(root, &to_send);
|
| -
|
| - Display* display = GetDisplay(root);
|
| - int64_t display_id =
|
| - display ? display->id() : display::Display::kInvalidDisplayID;
|
| - const ServerWindow* focused_window =
|
| - display ? display->GetFocusedWindow() : nullptr;
|
| - if (focused_window)
|
| - focused_window = access_policy_->GetWindowForFocusChange(focused_window);
|
| - ClientWindowId focused_window_id;
|
| - if (focused_window)
|
| - IsWindowKnown(focused_window, &focused_window_id);
|
| -
|
| - const bool drawn = root->parent() && root->parent()->IsDrawn();
|
| - client()->OnEmbed(id_, WindowToWindowData(to_send.front()), std::move(tree),
|
| - display_id, focused_window_id.id, drawn);
|
| -}
|
| -
|
| -void WindowTree::ConfigureWindowManager() {
|
| - DCHECK(!window_manager_internal_);
|
| - window_manager_internal_ = binding_->GetWindowManager();
|
| - window_manager_internal_->OnConnect(id_);
|
| - window_manager_state_.reset(new WindowManagerState(this));
|
| -}
|
| -
|
| -const ServerWindow* WindowTree::GetWindow(const WindowId& id) const {
|
| - if (id_ == id.client_id) {
|
| - auto iter = created_window_map_.find(id);
|
| - return iter == created_window_map_.end() ? nullptr : iter->second;
|
| - }
|
| - return window_server_->GetWindow(id);
|
| -}
|
| -
|
| -bool WindowTree::IsWindowKnown(const ServerWindow* window,
|
| - ClientWindowId* id) const {
|
| - if (!window)
|
| - return false;
|
| - auto iter = window_id_to_client_id_map_.find(window->id());
|
| - if (iter == window_id_to_client_id_map_.end())
|
| - return false;
|
| - if (id)
|
| - *id = iter->second;
|
| - return true;
|
| -}
|
| -
|
| -bool WindowTree::HasRoot(const ServerWindow* window) const {
|
| - return roots_.count(window) > 0;
|
| -}
|
| -
|
| -const ServerWindow* WindowTree::GetWindowByClientId(
|
| - const ClientWindowId& id) const {
|
| - auto iter = client_id_to_window_id_map_.find(id);
|
| - return iter == client_id_to_window_id_map_.end() ? nullptr
|
| - : GetWindow(iter->second);
|
| -}
|
| -
|
| -const Display* WindowTree::GetDisplay(const ServerWindow* window) const {
|
| - return window ? display_manager()->GetDisplayContaining(window) : nullptr;
|
| -}
|
| -
|
| -const WindowManagerDisplayRoot* WindowTree::GetWindowManagerDisplayRoot(
|
| - const ServerWindow* window) const {
|
| - return window ? display_manager()->GetWindowManagerDisplayRoot(window)
|
| - : nullptr;
|
| -}
|
| -
|
| -DisplayManager* WindowTree::display_manager() {
|
| - return window_server_->display_manager();
|
| -}
|
| -
|
| -const DisplayManager* WindowTree::display_manager() const {
|
| - return window_server_->display_manager();
|
| -}
|
| -
|
| -void WindowTree::AddRootForWindowManager(const ServerWindow* root) {
|
| - DCHECK(window_manager_internal_);
|
| - const ClientWindowId client_window_id(WindowIdToTransportId(root->id()));
|
| - DCHECK_EQ(0u, client_id_to_window_id_map_.count(client_window_id));
|
| - client_id_to_window_id_map_[client_window_id] = root->id();
|
| - window_id_to_client_id_map_[root->id()] = client_window_id;
|
| - roots_.insert(root);
|
| -
|
| - Display* display = GetDisplay(root);
|
| - DCHECK(display);
|
| -
|
| - window_manager_internal_->WmNewDisplayAdded(display->ToMojomDisplay(),
|
| - WindowToWindowData(root),
|
| - root->parent()->IsDrawn());
|
| -}
|
| -
|
| -void WindowTree::OnWindowDestroyingTreeImpl(WindowTree* tree) {
|
| - if (window_manager_state_)
|
| - window_manager_state_->OnWillDestroyTree(tree);
|
| -
|
| - if (event_source_wms_ && event_source_wms_->window_tree() == tree)
|
| - event_source_wms_ = nullptr;
|
| -
|
| - // Notify our client if |tree| was embedded in any of our views.
|
| - for (const auto* tree_root : tree->roots_) {
|
| - const bool owns_tree_root = tree_root->id().client_id == id_;
|
| - if (owns_tree_root) {
|
| - client()->OnEmbeddedAppDisconnected(
|
| - ClientWindowIdForWindow(tree_root).id);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WindowTree::NotifyChangeCompleted(
|
| - uint32_t change_id,
|
| - mojom::WindowManagerErrorCode error_code) {
|
| - client()->OnChangeCompleted(
|
| - change_id, error_code == mojom::WindowManagerErrorCode::SUCCESS);
|
| -}
|
| -
|
| -bool WindowTree::SetCapture(const ClientWindowId& client_window_id) {
|
| - ServerWindow* window = GetWindowByClientId(client_window_id);
|
| - WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window);
|
| - ServerWindow* current_capture_window =
|
| - display_root ? display_root->window_manager_state()->capture_window()
|
| - : nullptr;
|
| - if (window && window->IsDrawn() && display_root &&
|
| - display_root->window_manager_state()->IsActive() &&
|
| - access_policy_->CanSetCapture(window) &&
|
| - (!current_capture_window ||
|
| - access_policy_->CanSetCapture(current_capture_window))) {
|
| - return display_root->window_manager_state()->SetCapture(window, id_);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool WindowTree::NewWindow(
|
| - const ClientWindowId& client_window_id,
|
| - const std::map<std::string, std::vector<uint8_t>>& properties) {
|
| - if (!IsValidIdForNewWindow(client_window_id))
|
| - return false;
|
| - const WindowId window_id = GenerateNewWindowId();
|
| - DCHECK(!GetWindow(window_id));
|
| - ServerWindow* window =
|
| - window_server_->CreateServerWindow(window_id, properties);
|
| - created_window_map_[window_id] = window;
|
| - client_id_to_window_id_map_[client_window_id] = window_id;
|
| - window_id_to_client_id_map_[window_id] = client_window_id;
|
| - return true;
|
| -}
|
| -
|
| -bool WindowTree::AddWindow(const ClientWindowId& parent_id,
|
| - const ClientWindowId& child_id) {
|
| - ServerWindow* parent = GetWindowByClientId(parent_id);
|
| - ServerWindow* child = GetWindowByClientId(child_id);
|
| - if (parent && child && child->parent() != parent &&
|
| - !child->Contains(parent) && access_policy_->CanAddWindow(parent, child)) {
|
| - Operation op(this, window_server_, OperationType::ADD_WINDOW);
|
| - parent->Add(child);
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool WindowTree::AddTransientWindow(const ClientWindowId& window_id,
|
| - const ClientWindowId& transient_window_id) {
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - ServerWindow* transient_window = GetWindowByClientId(transient_window_id);
|
| - if (window && transient_window && !transient_window->Contains(window) &&
|
| - access_policy_->CanAddTransientWindow(window, transient_window)) {
|
| - Operation op(this, window_server_, OperationType::ADD_TRANSIENT_WINDOW);
|
| - return window->AddTransientWindow(transient_window);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool WindowTree::SetModal(const ClientWindowId& window_id) {
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - if (window && access_policy_->CanSetModal(window)) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - GetWindowManagerDisplayRoot(window);
|
| - if (window->transient_parent()) {
|
| - window->SetModal();
|
| - } else if (user_id_ != InvalidUserId()) {
|
| - if (display_root)
|
| - display_root->window_manager_state()->AddSystemModalWindow(window);
|
| - } else {
|
| - return false;
|
| - }
|
| - if (display_root)
|
| - display_root->window_manager_state()->ReleaseCaptureBlockedByModalWindow(
|
| - window);
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -std::vector<const ServerWindow*> WindowTree::GetWindowTree(
|
| - const ClientWindowId& window_id) const {
|
| - const ServerWindow* window = GetWindowByClientId(window_id);
|
| - std::vector<const ServerWindow*> windows;
|
| - if (window)
|
| - GetWindowTreeImpl(window, &windows);
|
| - return windows;
|
| -}
|
| -
|
| -bool WindowTree::SetWindowVisibility(const ClientWindowId& window_id,
|
| - bool visible) {
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - if (!window || !access_policy_->CanChangeWindowVisibility(window))
|
| - return false;
|
| - if (window->visible() == visible)
|
| - return true;
|
| - Operation op(this, window_server_, OperationType::SET_WINDOW_VISIBILITY);
|
| - window->SetVisible(visible);
|
| - return true;
|
| -}
|
| -
|
| -bool WindowTree::SetWindowOpacity(const ClientWindowId& window_id,
|
| - float opacity) {
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - if (!window || !access_policy_->CanChangeWindowOpacity(window))
|
| - return false;
|
| - if (window->opacity() == opacity)
|
| - return true;
|
| - Operation op(this, window_server_, OperationType::SET_WINDOW_OPACITY);
|
| - window->SetOpacity(opacity);
|
| - return true;
|
| -}
|
| -
|
| -bool WindowTree::SetFocus(const ClientWindowId& window_id) {
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - ServerWindow* currently_focused = window_server_->GetFocusedWindow();
|
| - if (!currently_focused && !window) {
|
| - DVLOG(1) << "SetFocus failure, no focused window to clear.";
|
| - return false;
|
| - }
|
| -
|
| - Display* display = GetDisplay(window);
|
| - if (window && (!display || !window->can_focus() || !window->IsDrawn())) {
|
| - DVLOG(1) << "SetFocus failure, window cannot be focused.";
|
| - return false;
|
| - }
|
| -
|
| - if (!access_policy_->CanSetFocus(window)) {
|
| - DVLOG(1) << "SetFocus failure, blocked by access policy.";
|
| - return false;
|
| - }
|
| -
|
| - Operation op(this, window_server_, OperationType::SET_FOCUS);
|
| - bool success = window_server_->SetFocusedWindow(window);
|
| - if (!success) {
|
| - DVLOG(1) << "SetFocus failure, could not SetFocusedWindow.";
|
| - }
|
| - return success;
|
| -}
|
| -
|
| -bool WindowTree::Embed(const ClientWindowId& window_id,
|
| - mojom::WindowTreeClientPtr client,
|
| - uint32_t flags) {
|
| - if (!client || !CanEmbed(window_id))
|
| - return false;
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - PrepareForEmbed(window);
|
| - // When embedding we don't know the user id of where the TreeClient came
|
| - // from. Use an invalid id, which limits what the client is able to do.
|
| - window_server_->EmbedAtWindow(window, InvalidUserId(), std::move(client),
|
| - flags,
|
| - base::WrapUnique(new DefaultAccessPolicy));
|
| - return true;
|
| -}
|
| -
|
| -void WindowTree::DispatchInputEvent(ServerWindow* target,
|
| - const ui::Event& event) {
|
| - if (event_ack_id_) {
|
| - // This is currently waiting for an event ack. Add it to the queue.
|
| - event_queue_.push(base::WrapUnique(new TargetedEvent(target, event)));
|
| - // TODO(sad): If the |event_queue_| grows too large, then this should notify
|
| - // Display, so that it can stop sending events.
|
| - return;
|
| - }
|
| -
|
| - // If there are events in the queue, then store this new event in the queue,
|
| - // and dispatch the latest event from the queue instead that still has a live
|
| - // target.
|
| - if (!event_queue_.empty()) {
|
| - event_queue_.push(base::WrapUnique(new TargetedEvent(target, event)));
|
| - return;
|
| - }
|
| -
|
| - DispatchInputEventImpl(target, event);
|
| -}
|
| -
|
| -bool WindowTree::IsWaitingForNewTopLevelWindow(uint32_t wm_change_id) {
|
| - return waiting_for_top_level_window_info_ &&
|
| - waiting_for_top_level_window_info_->wm_change_id == wm_change_id;
|
| -}
|
| -
|
| -void WindowTree::OnWindowManagerCreatedTopLevelWindow(
|
| - uint32_t wm_change_id,
|
| - uint32_t client_change_id,
|
| - const ServerWindow* window) {
|
| - DCHECK(IsWaitingForNewTopLevelWindow(wm_change_id));
|
| - std::unique_ptr<WaitingForTopLevelWindowInfo>
|
| - waiting_for_top_level_window_info(
|
| - std::move(waiting_for_top_level_window_info_));
|
| - binding_->SetIncomingMethodCallProcessingPaused(false);
|
| - // We were paused, so the id should still be valid.
|
| - DCHECK(IsValidIdForNewWindow(
|
| - waiting_for_top_level_window_info->client_window_id));
|
| - client_id_to_window_id_map_[waiting_for_top_level_window_info
|
| - ->client_window_id] = window->id();
|
| - window_id_to_client_id_map_[window->id()] =
|
| - waiting_for_top_level_window_info->client_window_id;
|
| - roots_.insert(window);
|
| - Display* display = GetDisplay(window);
|
| - int64_t display_id =
|
| - display ? display->id() : display::Display::kInvalidDisplayID;
|
| - const bool drawn = window->parent() && window->parent()->IsDrawn();
|
| - client()->OnTopLevelCreated(client_change_id, WindowToWindowData(window),
|
| - display_id, drawn);
|
| -}
|
| -
|
| -void WindowTree::AddActivationParent(const ClientWindowId& window_id) {
|
| - ServerWindow* window = GetWindowByClientId(window_id);
|
| - if (window) {
|
| - Display* display = GetDisplay(window);
|
| - if (display)
|
| - display->AddActivationParent(window);
|
| - else
|
| - DVLOG(1) << "AddActivationParent window not associated with display";
|
| - } else {
|
| - DVLOG(1) << "AddActivationParent supplied invalid window id";
|
| - }
|
| -}
|
| -
|
| -void WindowTree::OnChangeCompleted(uint32_t change_id, bool success) {
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::OnAccelerator(uint32_t accelerator_id,
|
| - const ui::Event& event) {
|
| - DCHECK(window_manager_internal_);
|
| - // TODO(moshayedi): crbug.com/617167. Don't clone even once we map
|
| - // mojom::Event directly to ui::Event.
|
| - window_manager_internal_->OnAccelerator(accelerator_id,
|
| - ui::Event::Clone(event));
|
| -}
|
| -
|
| -void WindowTree::ClientJankinessChanged(WindowTree* tree) {
|
| - tree->janky_ = !tree->janky_;
|
| - if (window_manager_internal_) {
|
| - window_manager_internal_->WmClientJankinessChanged(
|
| - tree->id(), tree->janky());
|
| - }
|
| -}
|
| -
|
| -void WindowTree::ProcessWindowBoundsChanged(const ServerWindow* window,
|
| - const gfx::Rect& old_bounds,
|
| - const gfx::Rect& new_bounds,
|
| - bool originated_change) {
|
| - ClientWindowId client_window_id;
|
| - if (originated_change || !IsWindowKnown(window, &client_window_id))
|
| - return;
|
| - client()->OnWindowBoundsChanged(client_window_id.id, old_bounds, new_bounds);
|
| -}
|
| -
|
| -void WindowTree::ProcessClientAreaChanged(
|
| - const ServerWindow* window,
|
| - const gfx::Insets& new_client_area,
|
| - const std::vector<gfx::Rect>& new_additional_client_areas,
|
| - bool originated_change) {
|
| - ClientWindowId client_window_id;
|
| - if (originated_change || !IsWindowKnown(window, &client_window_id))
|
| - return;
|
| - client()->OnClientAreaChanged(
|
| - client_window_id.id, new_client_area,
|
| - std::vector<gfx::Rect>(new_additional_client_areas));
|
| -}
|
| -
|
| -void WindowTree::ProcessWillChangeWindowHierarchy(
|
| - const ServerWindow* window,
|
| - const ServerWindow* new_parent,
|
| - const ServerWindow* old_parent,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| -
|
| - const bool old_drawn = window->IsDrawn();
|
| - const bool new_drawn =
|
| - window->visible() && new_parent && new_parent->IsDrawn();
|
| - if (old_drawn == new_drawn)
|
| - return;
|
| -
|
| - NotifyDrawnStateChanged(window, new_drawn);
|
| -}
|
| -
|
| -void WindowTree::ProcessWindowPropertyChanged(
|
| - const ServerWindow* window,
|
| - const std::string& name,
|
| - const std::vector<uint8_t>* new_data,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| -
|
| - ClientWindowId client_window_id;
|
| - if (!IsWindowKnown(window, &client_window_id))
|
| - return;
|
| -
|
| - Array<uint8_t> data(nullptr);
|
| - if (new_data)
|
| - data = Array<uint8_t>::From(*new_data);
|
| -
|
| - client()->OnWindowSharedPropertyChanged(client_window_id.id, String(name),
|
| - std::move(data));
|
| -}
|
| -
|
| -void WindowTree::ProcessWindowHierarchyChanged(const ServerWindow* window,
|
| - const ServerWindow* new_parent,
|
| - const ServerWindow* old_parent,
|
| - bool originated_change) {
|
| - const bool knows_new = new_parent && IsWindowKnown(new_parent);
|
| - if (originated_change && !IsWindowKnown(window) && knows_new) {
|
| - std::vector<const ServerWindow*> unused;
|
| - GetUnknownWindowsFrom(window, &unused);
|
| - }
|
| - if (originated_change || (window_server_->current_operation_type() ==
|
| - OperationType::DELETE_WINDOW) ||
|
| - (window_server_->current_operation_type() == OperationType::EMBED) ||
|
| - window_server_->DidTreeMessageClient(id_)) {
|
| - return;
|
| - }
|
| -
|
| - if (!access_policy_->ShouldNotifyOnHierarchyChange(window, &new_parent,
|
| - &old_parent)) {
|
| - return;
|
| - }
|
| - // Inform the client of any new windows and update the set of windows we know
|
| - // about.
|
| - std::vector<const ServerWindow*> to_send;
|
| - if (!IsWindowKnown(window))
|
| - GetUnknownWindowsFrom(window, &to_send);
|
| - const bool knows_old = old_parent && IsWindowKnown(old_parent);
|
| - if (!knows_old && !knows_new)
|
| - return;
|
| -
|
| - const ClientWindowId new_parent_client_window_id =
|
| - knows_new ? ClientWindowIdForWindow(new_parent) : ClientWindowId();
|
| - const ClientWindowId old_parent_client_window_id =
|
| - knows_old ? ClientWindowIdForWindow(old_parent) : ClientWindowId();
|
| - const ClientWindowId client_window_id =
|
| - window ? ClientWindowIdForWindow(window) : ClientWindowId();
|
| - client()->OnWindowHierarchyChanged(
|
| - client_window_id.id, old_parent_client_window_id.id,
|
| - new_parent_client_window_id.id, WindowsToWindowDatas(to_send));
|
| - window_server_->OnTreeMessagedClient(id_);
|
| -}
|
| -
|
| -void WindowTree::ProcessWindowReorder(const ServerWindow* window,
|
| - const ServerWindow* relative_window,
|
| - mojom::OrderDirection direction,
|
| - bool originated_change) {
|
| - DCHECK_EQ(window->parent(), relative_window->parent());
|
| - ClientWindowId client_window_id, relative_client_window_id;
|
| - if (originated_change || !IsWindowKnown(window, &client_window_id) ||
|
| - !IsWindowKnown(relative_window, &relative_client_window_id) ||
|
| - window_server_->DidTreeMessageClient(id_))
|
| - return;
|
| -
|
| - // Do not notify ordering changes of the root windows, since the client
|
| - // doesn't know about the ancestors of the roots, and so can't do anything
|
| - // about this ordering change of the root.
|
| - if (HasRoot(window) || HasRoot(relative_window))
|
| - return;
|
| -
|
| - client()->OnWindowReordered(client_window_id.id, relative_client_window_id.id,
|
| - direction);
|
| - window_server_->OnTreeMessagedClient(id_);
|
| -}
|
| -
|
| -void WindowTree::ProcessWindowDeleted(const ServerWindow* window,
|
| - bool originated_change) {
|
| - if (window->id().client_id == id_)
|
| - created_window_map_.erase(window->id());
|
| -
|
| - ClientWindowId client_window_id;
|
| - if (!IsWindowKnown(window, &client_window_id))
|
| - return;
|
| -
|
| - if (HasRoot(window))
|
| - RemoveRoot(window, RemoveRootReason::DELETED);
|
| - else
|
| - RemoveFromMaps(window);
|
| -
|
| - if (originated_change)
|
| - return;
|
| -
|
| - client()->OnWindowDeleted(client_window_id.id);
|
| - window_server_->OnTreeMessagedClient(id_);
|
| -}
|
| -
|
| -void WindowTree::ProcessWillChangeWindowVisibility(const ServerWindow* window,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| -
|
| - ClientWindowId client_window_id;
|
| - if (IsWindowKnown(window, &client_window_id)) {
|
| - client()->OnWindowVisibilityChanged(client_window_id.id,
|
| - !window->visible());
|
| - return;
|
| - }
|
| -
|
| - bool window_target_drawn_state;
|
| - if (window->visible()) {
|
| - // Window is being hidden, won't be drawn.
|
| - window_target_drawn_state = false;
|
| - } else {
|
| - // Window is being shown. Window will be drawn if its parent is drawn.
|
| - window_target_drawn_state = window->parent() && window->parent()->IsDrawn();
|
| - }
|
| -
|
| - NotifyDrawnStateChanged(window, window_target_drawn_state);
|
| -}
|
| -
|
| -void WindowTree::ProcessWindowOpacityChanged(const ServerWindow* window,
|
| - float old_opacity,
|
| - float new_opacity,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| -
|
| - ClientWindowId client_window_id;
|
| - if (IsWindowKnown(window, &client_window_id)) {
|
| - client()->OnWindowOpacityChanged(client_window_id.id, old_opacity,
|
| - new_opacity);
|
| - }
|
| -}
|
| -
|
| -void WindowTree::ProcessCursorChanged(const ServerWindow* window,
|
| - int32_t cursor_id,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| - ClientWindowId client_window_id;
|
| - if (!IsWindowKnown(window, &client_window_id))
|
| - return;
|
| -
|
| - client()->OnWindowPredefinedCursorChanged(client_window_id.id,
|
| - mojom::Cursor(cursor_id));
|
| -}
|
| -
|
| -void WindowTree::ProcessFocusChanged(const ServerWindow* old_focused_window,
|
| - const ServerWindow* new_focused_window) {
|
| - if (window_server_->current_operation_type() == OperationType::SET_FOCUS &&
|
| - window_server_->IsOperationSource(id_)) {
|
| - return;
|
| - }
|
| - const ServerWindow* window =
|
| - new_focused_window
|
| - ? access_policy_->GetWindowForFocusChange(new_focused_window)
|
| - : nullptr;
|
| - ClientWindowId client_window_id;
|
| - // If the window isn't known we'll supply null, which is ok.
|
| - IsWindowKnown(window, &client_window_id);
|
| - client()->OnWindowFocused(client_window_id.id);
|
| -}
|
| -
|
| -void WindowTree::ProcessTransientWindowAdded(
|
| - const ServerWindow* window,
|
| - const ServerWindow* transient_window,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| -
|
| - ClientWindowId client_window_id, transient_client_window_id;
|
| - if (!IsWindowKnown(window, &client_window_id) ||
|
| - !IsWindowKnown(transient_window, &transient_client_window_id)) {
|
| - return;
|
| - }
|
| - client()->OnTransientWindowAdded(client_window_id.id,
|
| - transient_client_window_id.id);
|
| -}
|
| -
|
| -void WindowTree::ProcessTransientWindowRemoved(
|
| - const ServerWindow* window,
|
| - const ServerWindow* transient_window,
|
| - bool originated_change) {
|
| - if (originated_change)
|
| - return;
|
| - ClientWindowId client_window_id, transient_client_window_id;
|
| - if (!IsWindowKnown(window, &client_window_id) ||
|
| - !IsWindowKnown(transient_window, &transient_client_window_id)) {
|
| - return;
|
| - }
|
| - client()->OnTransientWindowRemoved(client_window_id.id,
|
| - transient_client_window_id.id);
|
| -}
|
| -
|
| -bool WindowTree::ShouldRouteToWindowManager(const ServerWindow* window) const {
|
| - if (window_manager_state_)
|
| - return false; // We are the window manager, don't route to ourself.
|
| -
|
| - // If the client created this window, then do not route it through the WM.
|
| - if (window->id().client_id == id_)
|
| - return false;
|
| -
|
| - // If the client did not create the window, then it must be the root of the
|
| - // client. If not, that means the client should not know about this window,
|
| - // and so do not route the request to the WM.
|
| - if (roots_.count(window) == 0)
|
| - return false;
|
| -
|
| - // The WindowManager is attached to the root of the Display, if there isn't a
|
| - // WindowManager attached no need to route to it.
|
| - const WindowManagerDisplayRoot* display_root =
|
| - GetWindowManagerDisplayRoot(window);
|
| - if (!display_root)
|
| - return false;
|
| -
|
| - // Route to the windowmanager if the windowmanager created the window.
|
| - return display_root->window_manager_state()->window_tree()->id() ==
|
| - window->id().client_id;
|
| -}
|
| -
|
| -void WindowTree::ProcessLostCapture(const ServerWindow* old_capture_window,
|
| - bool originated_change) {
|
| - if ((originated_change &&
|
| - window_server_->current_operation_type() ==
|
| - OperationType::RELEASE_CAPTURE) ||
|
| - !IsWindowKnown(old_capture_window)) {
|
| - return;
|
| - }
|
| - client()->OnLostCapture(WindowIdToTransportId(old_capture_window->id()));
|
| -}
|
| -
|
| -ClientWindowId WindowTree::ClientWindowIdForWindow(
|
| - const ServerWindow* window) const {
|
| - auto iter = window_id_to_client_id_map_.find(window->id());
|
| - DCHECK(iter != window_id_to_client_id_map_.end());
|
| - return iter->second;
|
| -}
|
| -
|
| -bool WindowTree::IsValidIdForNewWindow(const ClientWindowId& id) const {
|
| - // Reserve 0 to indicate a null window.
|
| - return client_id_to_window_id_map_.count(id) == 0u &&
|
| - access_policy_->IsValidIdForNewWindow(id) && id != ClientWindowId();
|
| -}
|
| -
|
| -WindowId WindowTree::GenerateNewWindowId() {
|
| - // TODO(sky): deal with wrapping and uniqueness.
|
| - return WindowId(id_, next_window_id_++);
|
| -}
|
| -
|
| -bool WindowTree::CanReorderWindow(const ServerWindow* window,
|
| - const ServerWindow* relative_window,
|
| - mojom::OrderDirection direction) const {
|
| - if (!window || !relative_window)
|
| - return false;
|
| -
|
| - if (!window->parent() || window->parent() != relative_window->parent())
|
| - return false;
|
| -
|
| - if (!access_policy_->CanReorderWindow(window, relative_window, direction))
|
| - return false;
|
| -
|
| - std::vector<const ServerWindow*> children = window->parent()->GetChildren();
|
| - const size_t child_i =
|
| - std::find(children.begin(), children.end(), window) - children.begin();
|
| - const size_t target_i =
|
| - std::find(children.begin(), children.end(), relative_window) -
|
| - children.begin();
|
| - if ((direction == mojom::OrderDirection::ABOVE && child_i == target_i + 1) ||
|
| - (direction == mojom::OrderDirection::BELOW && child_i + 1 == target_i)) {
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool WindowTree::DeleteWindowImpl(WindowTree* source, ServerWindow* window) {
|
| - DCHECK(window);
|
| - DCHECK_EQ(window->id().client_id, id_);
|
| - Operation op(source, window_server_, OperationType::DELETE_WINDOW);
|
| - delete window;
|
| - return true;
|
| -}
|
| -
|
| -void WindowTree::GetUnknownWindowsFrom(
|
| - const ServerWindow* window,
|
| - std::vector<const ServerWindow*>* windows) {
|
| - if (IsWindowKnown(window) || !access_policy_->CanGetWindowTree(window))
|
| - return;
|
| - windows->push_back(window);
|
| - // There are two cases where this gets hit:
|
| - // . During init, in which case using the window id as the client id is
|
| - // fine.
|
| - // . When a window is moved to a parent of a window we know about. This is
|
| - // only encountered for the WM or embed roots. We assume such clients want
|
| - // to see the real id of the window and are only created ClientWindowIds
|
| - // with the client_id.
|
| - const ClientWindowId client_window_id(WindowIdToTransportId(window->id()));
|
| - DCHECK_EQ(0u, client_id_to_window_id_map_.count(client_window_id));
|
| - client_id_to_window_id_map_[client_window_id] = window->id();
|
| - window_id_to_client_id_map_[window->id()] = client_window_id;
|
| - if (!access_policy_->CanDescendIntoWindowForWindowTree(window))
|
| - return;
|
| - std::vector<const ServerWindow*> children(window->GetChildren());
|
| - for (size_t i = 0; i < children.size(); ++i)
|
| - GetUnknownWindowsFrom(children[i], windows);
|
| -}
|
| -
|
| -bool WindowTree::RemoveFromMaps(const ServerWindow* window) {
|
| - auto iter = window_id_to_client_id_map_.find(window->id());
|
| - if (iter == window_id_to_client_id_map_.end())
|
| - return false;
|
| -
|
| - client_id_to_window_id_map_.erase(iter->second);
|
| - window_id_to_client_id_map_.erase(iter);
|
| - return true;
|
| -}
|
| -
|
| -void WindowTree::RemoveFromKnown(const ServerWindow* window,
|
| - std::vector<ServerWindow*>* local_windows) {
|
| - if (window->id().client_id == id_) {
|
| - if (local_windows)
|
| - local_windows->push_back(GetWindow(window->id()));
|
| - return;
|
| - }
|
| -
|
| - RemoveFromMaps(window);
|
| -
|
| - std::vector<const ServerWindow*> children = window->GetChildren();
|
| - for (size_t i = 0; i < children.size(); ++i)
|
| - RemoveFromKnown(children[i], local_windows);
|
| -}
|
| -
|
| -void WindowTree::RemoveRoot(const ServerWindow* window,
|
| - RemoveRootReason reason) {
|
| - DCHECK(roots_.count(window) > 0);
|
| - roots_.erase(window);
|
| -
|
| - const ClientWindowId client_window_id(ClientWindowIdForWindow(window));
|
| -
|
| - // No need to do anything if we created the window.
|
| - if (window->id().client_id == id_)
|
| - return;
|
| -
|
| - if (reason == RemoveRootReason::EMBED) {
|
| - client()->OnUnembed(client_window_id.id);
|
| - client()->OnWindowDeleted(client_window_id.id);
|
| - window_server_->OnTreeMessagedClient(id_);
|
| - }
|
| -
|
| - // This client no longer knows about the window. Unparent any windows that
|
| - // were parented to windows in the root.
|
| - std::vector<ServerWindow*> local_windows;
|
| - RemoveFromKnown(window, &local_windows);
|
| - for (size_t i = 0; i < local_windows.size(); ++i)
|
| - local_windows[i]->parent()->Remove(local_windows[i]);
|
| -}
|
| -
|
| -Array<mojom::WindowDataPtr> WindowTree::WindowsToWindowDatas(
|
| - const std::vector<const ServerWindow*>& windows) {
|
| - Array<mojom::WindowDataPtr> array(windows.size());
|
| - for (size_t i = 0; i < windows.size(); ++i)
|
| - array[i] = WindowToWindowData(windows[i]);
|
| - return array;
|
| -}
|
| -
|
| -mojom::WindowDataPtr WindowTree::WindowToWindowData(
|
| - const ServerWindow* window) {
|
| - DCHECK(IsWindowKnown(window));
|
| - const ServerWindow* parent = window->parent();
|
| - // If the parent isn't known, it means the parent is not visible to us (not
|
| - // in roots), and should not be sent over.
|
| - if (parent && !IsWindowKnown(parent))
|
| - parent = nullptr;
|
| - mojom::WindowDataPtr window_data(mojom::WindowData::New());
|
| - window_data->parent_id =
|
| - parent ? ClientWindowIdForWindow(parent).id : ClientWindowId().id;
|
| - window_data->window_id =
|
| - window ? ClientWindowIdForWindow(window).id : ClientWindowId().id;
|
| - window_data->bounds = window->bounds();
|
| - window_data->properties =
|
| - mojo::Map<String, Array<uint8_t>>::From(window->properties());
|
| - window_data->visible = window->visible();
|
| - return window_data;
|
| -}
|
| -
|
| -void WindowTree::GetWindowTreeImpl(
|
| - const ServerWindow* window,
|
| - std::vector<const ServerWindow*>* windows) const {
|
| - DCHECK(window);
|
| -
|
| - if (!access_policy_->CanGetWindowTree(window))
|
| - return;
|
| -
|
| - windows->push_back(window);
|
| -
|
| - if (!access_policy_->CanDescendIntoWindowForWindowTree(window))
|
| - return;
|
| -
|
| - std::vector<const ServerWindow*> children(window->GetChildren());
|
| - for (size_t i = 0; i < children.size(); ++i)
|
| - GetWindowTreeImpl(children[i], windows);
|
| -}
|
| -
|
| -void WindowTree::NotifyDrawnStateChanged(const ServerWindow* window,
|
| - bool new_drawn_value) {
|
| - // Even though we don't know about window, it may be an ancestor of our root,
|
| - // in which case the change may effect our roots drawn state.
|
| - if (roots_.empty())
|
| - return;
|
| -
|
| - for (auto* root : roots_) {
|
| - if (window->Contains(root) && (new_drawn_value != root->IsDrawn())) {
|
| - client()->OnWindowParentDrawnStateChanged(
|
| - ClientWindowIdForWindow(root).id, new_drawn_value);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WindowTree::DestroyWindows() {
|
| - if (created_window_map_.empty())
|
| - return;
|
| -
|
| - Operation op(this, window_server_, OperationType::DELETE_WINDOW);
|
| - // If we get here from the destructor we're not going to get
|
| - // ProcessWindowDeleted(). Copy the map and delete from the copy so that we
|
| - // don't have to worry about whether |created_window_map_| changes or not.
|
| - base::hash_map<WindowId, ServerWindow*> created_window_map_copy;
|
| - created_window_map_.swap(created_window_map_copy);
|
| - // A sibling can be a transient parent of another window so we detach windows
|
| - // from their transient parents to avoid double deletes.
|
| - for (auto& pair : created_window_map_copy) {
|
| - ServerWindow* transient_parent = pair.second->transient_parent();
|
| - if (transient_parent)
|
| - transient_parent->RemoveTransientWindow(pair.second);
|
| - }
|
| - STLDeleteValues(&created_window_map_copy);
|
| -}
|
| -
|
| -bool WindowTree::CanEmbed(const ClientWindowId& window_id) const {
|
| - const ServerWindow* window = GetWindowByClientId(window_id);
|
| - return window && access_policy_->CanEmbed(window);
|
| -}
|
| -
|
| -void WindowTree::PrepareForEmbed(ServerWindow* window) {
|
| - DCHECK(window);
|
| -
|
| - // Only allow a node to be the root for one client.
|
| - WindowTree* existing_owner = window_server_->GetTreeWithRoot(window);
|
| -
|
| - Operation op(this, window_server_, OperationType::EMBED);
|
| - RemoveChildrenAsPartOfEmbed(window);
|
| - if (existing_owner) {
|
| - // Never message the originating client.
|
| - window_server_->OnTreeMessagedClient(id_);
|
| - existing_owner->RemoveRoot(window, RemoveRootReason::EMBED);
|
| - }
|
| -}
|
| -
|
| -void WindowTree::RemoveChildrenAsPartOfEmbed(ServerWindow* window) {
|
| - CHECK(window);
|
| - std::vector<ServerWindow*> children = window->GetChildren();
|
| - for (size_t i = 0; i < children.size(); ++i)
|
| - window->Remove(children[i]);
|
| -}
|
| -
|
| -void WindowTree::DispatchInputEventImpl(ServerWindow* target,
|
| - const ui::Event& event) {
|
| - DCHECK(!event_ack_id_);
|
| - // We do not want to create a sequential id for each event, because that can
|
| - // leak some information to the client. So instead, manufacture the id
|
| - // randomly.
|
| - // TODO(moshayedi): Find a faster way to generate ids.
|
| - event_ack_id_ = 0x1000000 | (rand() & 0xffffff);
|
| - WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(target);
|
| - DCHECK(display_root);
|
| - event_source_wms_ = display_root->window_manager_state();
|
| - // Should only get events from windows attached to a host.
|
| - DCHECK(event_source_wms_);
|
| - bool matched_observer =
|
| - event_observer_matcher_ && event_observer_matcher_->MatchesEvent(event);
|
| - client()->OnWindowInputEvent(
|
| - event_ack_id_, ClientWindowIdForWindow(target).id,
|
| - ui::Event::Clone(event), matched_observer ? event_observer_id_ : 0);
|
| -}
|
| -
|
| -void WindowTree::SendToEventObserver(const ui::Event& event) {
|
| - if (event_observer_matcher_ && event_observer_matcher_->MatchesEvent(event))
|
| - client()->OnEventObserved(ui::Event::Clone(event), event_observer_id_);
|
| -}
|
| -
|
| -void WindowTree::NewWindow(
|
| - uint32_t change_id,
|
| - Id transport_window_id,
|
| - mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) {
|
| - std::map<std::string, std::vector<uint8_t>> properties;
|
| - if (!transport_properties.is_null()) {
|
| - properties =
|
| - transport_properties.To<std::map<std::string, std::vector<uint8_t>>>();
|
| - }
|
| - client()->OnChangeCompleted(
|
| - change_id, NewWindow(ClientWindowId(transport_window_id), properties));
|
| -}
|
| -
|
| -void WindowTree::NewTopLevelWindow(
|
| - uint32_t change_id,
|
| - Id transport_window_id,
|
| - mojo::Map<mojo::String, mojo::Array<uint8_t>> transport_properties) {
|
| - DCHECK(!waiting_for_top_level_window_info_);
|
| - const ClientWindowId client_window_id(transport_window_id);
|
| - // TODO(sky): need a way for client to provide context to figure out display.
|
| - Display* display = display_manager()->displays().empty()
|
| - ? nullptr
|
| - : *(display_manager()->displays().begin());
|
| - // TODO(sky): move checks to accesspolicy.
|
| - WindowManagerDisplayRoot* display_root =
|
| - display && user_id_ != InvalidUserId()
|
| - ? display->GetWindowManagerDisplayRootForUser(user_id_)
|
| - : nullptr;
|
| - if (!display_root ||
|
| - display_root->window_manager_state()->window_tree() == this ||
|
| - !IsValidIdForNewWindow(client_window_id)) {
|
| - client()->OnChangeCompleted(change_id, false);
|
| - return;
|
| - }
|
| -
|
| - // The server creates the real window. Any further messages from the client
|
| - // may try to alter the window. Pause incoming messages so that we know we
|
| - // can't get a message for a window before the window is created. Once the
|
| - // window is created we'll resume processing.
|
| - binding_->SetIncomingMethodCallProcessingPaused(true);
|
| -
|
| - const uint32_t wm_change_id =
|
| - window_server_->GenerateWindowManagerChangeId(this, change_id);
|
| -
|
| - waiting_for_top_level_window_info_.reset(
|
| - new WaitingForTopLevelWindowInfo(client_window_id, wm_change_id));
|
| -
|
| - display_root->window_manager_state()
|
| - ->window_tree()
|
| - ->window_manager_internal_->WmCreateTopLevelWindow(
|
| - wm_change_id, id_, std::move(transport_properties));
|
| -}
|
| -
|
| -void WindowTree::DeleteWindow(uint32_t change_id, Id transport_window_id) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - bool success = false;
|
| - bool should_close = window && (access_policy_->CanDeleteWindow(window) ||
|
| - ShouldRouteToWindowManager(window));
|
| - if (should_close) {
|
| - WindowTree* tree =
|
| - window_server_->GetTreeWithId(window->id().client_id);
|
| - success = tree && tree->DeleteWindowImpl(this, window);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::AddWindow(uint32_t change_id, Id parent_id, Id child_id) {
|
| - client()->OnChangeCompleted(change_id, AddWindow(ClientWindowId(parent_id),
|
| - ClientWindowId(child_id)));
|
| -}
|
| -
|
| -void WindowTree::RemoveWindowFromParent(uint32_t change_id, Id window_id) {
|
| - bool success = false;
|
| - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
|
| - if (window && window->parent() &&
|
| - access_policy_->CanRemoveWindowFromParent(window)) {
|
| - success = true;
|
| - Operation op(this, window_server_,
|
| - OperationType::REMOVE_WINDOW_FROM_PARENT);
|
| - window->parent()->Remove(window);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::AddTransientWindow(uint32_t change_id,
|
| - Id window,
|
| - Id transient_window) {
|
| - client()->OnChangeCompleted(
|
| - change_id, AddTransientWindow(ClientWindowId(window),
|
| - ClientWindowId(transient_window)));
|
| -}
|
| -
|
| -void WindowTree::RemoveTransientWindowFromParent(uint32_t change_id,
|
| - Id transient_window_id) {
|
| - bool success = false;
|
| - ServerWindow* transient_window =
|
| - GetWindowByClientId(ClientWindowId(transient_window_id));
|
| - if (transient_window && transient_window->transient_parent() &&
|
| - access_policy_->CanRemoveTransientWindowFromParent(transient_window)) {
|
| - success = true;
|
| - Operation op(this, window_server_,
|
| - OperationType::REMOVE_TRANSIENT_WINDOW_FROM_PARENT);
|
| - transient_window->transient_parent()->RemoveTransientWindow(
|
| - transient_window);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::SetModal(uint32_t change_id, Id window_id) {
|
| - client()->OnChangeCompleted(change_id, SetModal(ClientWindowId(window_id)));
|
| -}
|
| -
|
| -void WindowTree::ReorderWindow(uint32_t change_id,
|
| - Id window_id,
|
| - Id relative_window_id,
|
| - mojom::OrderDirection direction) {
|
| - bool success = false;
|
| - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
|
| - ServerWindow* relative_window =
|
| - GetWindowByClientId(ClientWindowId(relative_window_id));
|
| - if (CanReorderWindow(window, relative_window, direction)) {
|
| - success = true;
|
| - Operation op(this, window_server_, OperationType::REORDER_WINDOW);
|
| - window->Reorder(relative_window, direction);
|
| - window_server_->ProcessWindowReorder(window, relative_window, direction);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::GetWindowTree(
|
| - Id window_id,
|
| - const base::Callback<void(Array<mojom::WindowDataPtr>)>& callback) {
|
| - std::vector<const ServerWindow*> windows(
|
| - GetWindowTree(ClientWindowId(window_id)));
|
| - callback.Run(WindowsToWindowDatas(windows));
|
| -}
|
| -
|
| -void WindowTree::SetCapture(uint32_t change_id, Id window_id) {
|
| - client()->OnChangeCompleted(change_id, SetCapture(ClientWindowId(window_id)));
|
| -}
|
| -
|
| -void WindowTree::ReleaseCapture(uint32_t change_id, Id window_id) {
|
| - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
|
| - WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window);
|
| - ServerWindow* current_capture_window =
|
| - display_root ? display_root->window_manager_state()->capture_window()
|
| - : nullptr;
|
| - bool success = window && display_root &&
|
| - display_root->window_manager_state()->IsActive() &&
|
| - (!current_capture_window ||
|
| - access_policy_->CanSetCapture(current_capture_window)) &&
|
| - window == current_capture_window;
|
| - if (success) {
|
| - Operation op(this, window_server_, OperationType::RELEASE_CAPTURE);
|
| - success = display_root->window_manager_state()->SetCapture(
|
| - nullptr, kInvalidClientId);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::SetEventObserver(mojom::EventMatcherPtr matcher,
|
| - uint32_t observer_id) {
|
| - if (matcher.is_null() || observer_id == 0) {
|
| - // Clear any existing event observer.
|
| - event_observer_matcher_.reset();
|
| - event_observer_id_ = 0;
|
| - return;
|
| - }
|
| -
|
| - // Do not allow key events to be observed, as a compromised app could register
|
| - // itself as an event observer and spy on keystrokes to another app.
|
| - if (!matcher->type_matcher) {
|
| - DVLOG(1) << "SetEventObserver must specify an event type.";
|
| - return;
|
| - }
|
| - const ui::mojom::EventType event_type_whitelist[] = {
|
| - ui::mojom::EventType::POINTER_CANCEL, ui::mojom::EventType::POINTER_DOWN,
|
| - ui::mojom::EventType::POINTER_MOVE, ui::mojom::EventType::POINTER_UP,
|
| - ui::mojom::EventType::MOUSE_EXIT, ui::mojom::EventType::WHEEL,
|
| - };
|
| - bool allowed = false;
|
| - for (ui::mojom::EventType event_type : event_type_whitelist) {
|
| - if (matcher->type_matcher->type == event_type) {
|
| - allowed = true;
|
| - break;
|
| - }
|
| - }
|
| - if (!allowed) {
|
| - DVLOG(1) << "SetEventObserver event type not allowed";
|
| - return;
|
| - }
|
| -
|
| - event_observer_matcher_.reset(new EventMatcher(*matcher));
|
| - event_observer_id_ = observer_id;
|
| -}
|
| -
|
| -void WindowTree::SetWindowBounds(uint32_t change_id,
|
| - Id window_id,
|
| - const gfx::Rect& bounds) {
|
| - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
|
| - if (window && ShouldRouteToWindowManager(window)) {
|
| - const uint32_t wm_change_id =
|
| - window_server_->GenerateWindowManagerChangeId(this, change_id);
|
| - // |window_id| may be a client id, use the id from the window to ensure
|
| - // the windowmanager doesn't get an id it doesn't know about.
|
| - WindowManagerDisplayRoot* display_root =
|
| - GetWindowManagerDisplayRoot(window);
|
| - WindowTree* wm_tree = display_root->window_manager_state()->window_tree();
|
| - wm_tree->window_manager_internal_->WmSetBounds(
|
| - wm_change_id, wm_tree->ClientWindowIdForWindow(window).id,
|
| - std::move(bounds));
|
| - return;
|
| - }
|
| -
|
| - // Only the owner of the window can change the bounds.
|
| - bool success = window && access_policy_->CanSetWindowBounds(window);
|
| - if (success) {
|
| - Operation op(this, window_server_, OperationType::SET_WINDOW_BOUNDS);
|
| - window->SetBounds(bounds);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::SetWindowVisibility(uint32_t change_id,
|
| - Id transport_window_id,
|
| - bool visible) {
|
| - client()->OnChangeCompleted(
|
| - change_id,
|
| - SetWindowVisibility(ClientWindowId(transport_window_id), visible));
|
| -}
|
| -
|
| -void WindowTree::SetWindowProperty(uint32_t change_id,
|
| - Id transport_window_id,
|
| - const mojo::String& name,
|
| - mojo::Array<uint8_t> value) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - if (window && ShouldRouteToWindowManager(window)) {
|
| - const uint32_t wm_change_id =
|
| - window_server_->GenerateWindowManagerChangeId(this, change_id);
|
| - WindowManagerDisplayRoot* display_root =
|
| - GetWindowManagerDisplayRoot(window);
|
| - WindowTree* wm_tree = display_root->window_manager_state()->window_tree();
|
| - wm_tree->window_manager_internal_->WmSetProperty(
|
| - wm_change_id, wm_tree->ClientWindowIdForWindow(window).id, name,
|
| - std::move(value));
|
| - return;
|
| - }
|
| - const bool success = window && access_policy_->CanSetWindowProperties(window);
|
| - if (success) {
|
| - Operation op(this, window_server_, OperationType::SET_WINDOW_PROPERTY);
|
| - if (value.is_null()) {
|
| - window->SetProperty(name, nullptr);
|
| - } else {
|
| - std::vector<uint8_t> data = value.To<std::vector<uint8_t>>();
|
| - window->SetProperty(name, &data);
|
| - }
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::SetWindowOpacity(uint32_t change_id,
|
| - Id window_id,
|
| - float opacity) {
|
| - client()->OnChangeCompleted(
|
| - change_id, SetWindowOpacity(ClientWindowId(window_id), opacity));
|
| -}
|
| -
|
| -void WindowTree::AttachSurface(Id transport_window_id,
|
| - mojom::SurfaceType type,
|
| - mojo::InterfaceRequest<mojom::Surface> surface,
|
| - mojom::SurfaceClientPtr client) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - const bool success =
|
| - window && access_policy_->CanSetWindowSurface(window, type);
|
| - if (!success)
|
| - return;
|
| - window->CreateSurface(type, std::move(surface), std::move(client));
|
| -}
|
| -
|
| -void WindowTree::SetWindowTextInputState(Id transport_window_id,
|
| - mojo::TextInputStatePtr state) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - bool success = window && access_policy_->CanSetWindowTextInputState(window);
|
| - if (success)
|
| - window->SetTextInputState(state.To<ui::TextInputState>());
|
| -}
|
| -
|
| -void WindowTree::SetImeVisibility(Id transport_window_id,
|
| - bool visible,
|
| - mojo::TextInputStatePtr state) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - bool success = window && access_policy_->CanSetWindowTextInputState(window);
|
| - if (success) {
|
| - if (!state.is_null())
|
| - window->SetTextInputState(state.To<ui::TextInputState>());
|
| -
|
| - Display* display = GetDisplay(window);
|
| - if (display)
|
| - display->SetImeVisibility(window, visible);
|
| - }
|
| -}
|
| -
|
| -void WindowTree::OnWindowInputEventAck(uint32_t event_id,
|
| - mojom::EventResult result) {
|
| - if (event_ack_id_ == 0 || event_id != event_ack_id_) {
|
| - // TODO(sad): Something bad happened. Kill the client?
|
| - NOTIMPLEMENTED() << "Wrong event acked.";
|
| - }
|
| - event_ack_id_ = 0;
|
| -
|
| - if (janky_)
|
| - event_source_wms_->window_tree()->ClientJankinessChanged(this);
|
| -
|
| - WindowManagerState* event_source_wms = event_source_wms_;
|
| - event_source_wms_ = nullptr;
|
| - if (event_source_wms)
|
| - event_source_wms->OnEventAck(this, result);
|
| -
|
| - if (!event_queue_.empty()) {
|
| - DCHECK(!event_ack_id_);
|
| - ServerWindow* target = nullptr;
|
| - std::unique_ptr<ui::Event> event;
|
| - do {
|
| - std::unique_ptr<TargetedEvent> targeted_event =
|
| - std::move(event_queue_.front());
|
| - event_queue_.pop();
|
| - target = targeted_event->target();
|
| - event = targeted_event->TakeEvent();
|
| - } while (!event_queue_.empty() && !GetDisplay(target));
|
| - if (target)
|
| - DispatchInputEventImpl(target, *event);
|
| - }
|
| -}
|
| -
|
| -void WindowTree::SetClientArea(
|
| - Id transport_window_id,
|
| - const gfx::Insets& insets,
|
| - mojo::Array<gfx::Rect> transport_additional_client_areas) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - if (!window || !access_policy_->CanSetClientArea(window))
|
| - return;
|
| -
|
| - std::vector<gfx::Rect> additional_client_areas =
|
| - transport_additional_client_areas.To<std::vector<gfx::Rect>>();
|
| - window->SetClientArea(insets, additional_client_areas);
|
| -}
|
| -
|
| -void WindowTree::SetHitTestMask(Id transport_window_id, const gfx::Rect& mask) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - if (!window || !access_policy_->CanSetHitTestMask(window)) {
|
| - DVLOG(1) << "SetHitTestMask failed";
|
| - return;
|
| - }
|
| -
|
| - if (!mask.IsEmpty())
|
| - window->SetHitTestMask(mask);
|
| - else
|
| - window->ClearHitTestMask();
|
| -}
|
| -
|
| -void WindowTree::Embed(Id transport_window_id,
|
| - mojom::WindowTreeClientPtr client,
|
| - uint32_t flags,
|
| - const EmbedCallback& callback) {
|
| - callback.Run(
|
| - Embed(ClientWindowId(transport_window_id), std::move(client), flags));
|
| -}
|
| -
|
| -void WindowTree::SetFocus(uint32_t change_id, Id transport_window_id) {
|
| - client()->OnChangeCompleted(change_id,
|
| - SetFocus(ClientWindowId(transport_window_id)));
|
| -}
|
| -
|
| -void WindowTree::SetCanFocus(Id transport_window_id, bool can_focus) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - // TODO(sky): there should be an else case (it shouldn't route to wm and
|
| - // policy allows, then set_can_focus).
|
| - if (window && ShouldRouteToWindowManager(window))
|
| - window->set_can_focus(can_focus);
|
| -}
|
| -
|
| -void WindowTree::SetPredefinedCursor(uint32_t change_id,
|
| - Id transport_window_id,
|
| - mus::mojom::Cursor cursor_id) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| -
|
| - // Only the owner of the window can change the bounds.
|
| - bool success = window && access_policy_->CanSetCursorProperties(window);
|
| - if (success) {
|
| - Operation op(this, window_server_,
|
| - OperationType::SET_WINDOW_PREDEFINED_CURSOR);
|
| - window->SetPredefinedCursor(cursor_id);
|
| - }
|
| - client()->OnChangeCompleted(change_id, success);
|
| -}
|
| -
|
| -void WindowTree::GetWindowManagerClient(
|
| - mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal) {
|
| - if (!access_policy_->CanSetWindowManager() || !window_manager_internal_ ||
|
| - window_manager_internal_client_binding_) {
|
| - return;
|
| - }
|
| - window_manager_internal_client_binding_.reset(
|
| - new mojo::AssociatedBinding<mojom::WindowManagerClient>(
|
| - this, std::move(internal)));
|
| -}
|
| -
|
| -void WindowTree::GetCursorLocationMemory(
|
| - const GetCursorLocationMemoryCallback& callback) {
|
| - callback.Run(
|
| - window_server_->display_manager()->GetUserDisplayManager(user_id_)->
|
| - GetCursorLocationMemory());
|
| -}
|
| -
|
| -void WindowTree::AddAccelerator(uint32_t id,
|
| - mojom::EventMatcherPtr event_matcher,
|
| - const AddAcceleratorCallback& callback) {
|
| - DCHECK(window_manager_state_);
|
| - const bool success =
|
| - window_manager_state_->event_dispatcher()->AddAccelerator(
|
| - id, std::move(event_matcher));
|
| - callback.Run(success);
|
| -}
|
| -
|
| -void WindowTree::RemoveAccelerator(uint32_t id) {
|
| - window_manager_state_->event_dispatcher()->RemoveAccelerator(id);
|
| -}
|
| -
|
| -void WindowTree::AddActivationParent(Id transport_window_id) {
|
| - AddActivationParent(ClientWindowId(transport_window_id));
|
| -}
|
| -
|
| -void WindowTree::RemoveActivationParent(Id transport_window_id) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - if (window) {
|
| - Display* display = GetDisplay(window);
|
| - if (display)
|
| - display->RemoveActivationParent(window);
|
| - else
|
| - DVLOG(1) << "RemoveActivationParent window not associated with display";
|
| - } else {
|
| - DVLOG(1) << "RemoveActivationParent supplied invalid window id";
|
| - }
|
| -}
|
| -
|
| -void WindowTree::ActivateNextWindow() {
|
| - DCHECK(window_manager_state_);
|
| - if (window_server_->user_id_tracker()->active_id() != user_id_)
|
| - return;
|
| -
|
| - ServerWindow* focused_window = window_server_->GetFocusedWindow();
|
| - if (focused_window) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - GetWindowManagerDisplayRoot(focused_window);
|
| - if (display_root->window_manager_state() != window_manager_state_.get()) {
|
| - // We aren't active.
|
| - return;
|
| - }
|
| - display_root->display()->ActivateNextWindow();
|
| - return;
|
| - }
|
| - // Use the first display.
|
| - std::set<Display*> displays = window_server_->display_manager()->displays();
|
| - if (displays.empty())
|
| - return;
|
| -
|
| - (*displays.begin())->ActivateNextWindow();
|
| -}
|
| -
|
| -void WindowTree::SetUnderlaySurfaceOffsetAndExtendedHitArea(
|
| - Id window_id,
|
| - int32_t x_offset,
|
| - int32_t y_offset,
|
| - const gfx::Insets& hit_area) {
|
| - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
|
| - if (!window)
|
| - return;
|
| -
|
| - window->SetUnderlayOffset(gfx::Vector2d(x_offset, y_offset));
|
| - window->set_extended_hit_test_region(hit_area);
|
| -}
|
| -
|
| -void WindowTree::WmResponse(uint32_t change_id, bool response) {
|
| - window_server_->WindowManagerChangeCompleted(change_id, response);
|
| -}
|
| -
|
| -void WindowTree::WmRequestClose(Id transport_window_id) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - WindowTree* tree = window_server_->GetTreeWithRoot(window);
|
| - if (tree && tree != this) {
|
| - tree->client()->RequestClose(tree->ClientWindowIdForWindow(window).id);
|
| - }
|
| - // TODO(sky): think about what else case means.
|
| -}
|
| -
|
| -void WindowTree::WmSetFrameDecorationValues(
|
| - mojom::FrameDecorationValuesPtr values) {
|
| - DCHECK(window_manager_state_);
|
| - window_manager_state_->SetFrameDecorationValues(std::move(values));
|
| -}
|
| -
|
| -void WindowTree::WmSetNonClientCursor(uint32_t window_id,
|
| - mojom::Cursor cursor_id) {
|
| - DCHECK(window_manager_state_);
|
| - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
|
| - if (window) {
|
| - window->SetNonClientCursor(cursor_id);
|
| - } else {
|
| - DVLOG(1) << "trying to update non-client cursor of invalid window";
|
| - }
|
| -}
|
| -
|
| -void WindowTree::OnWmCreatedTopLevelWindow(uint32_t change_id,
|
| - Id transport_window_id) {
|
| - ServerWindow* window =
|
| - GetWindowByClientId(ClientWindowId(transport_window_id));
|
| - if (window && window->id().client_id != id_) {
|
| - DVLOG(1) << "OnWmCreatedTopLevelWindow supplied invalid window id";
|
| - window_server_->WindowManagerSentBogusMessage();
|
| - window = nullptr;
|
| - }
|
| - window_server_->WindowManagerCreatedTopLevelWindow(this, change_id, window);
|
| -}
|
| -
|
| -bool WindowTree::HasRootForAccessPolicy(const ServerWindow* window) const {
|
| - return HasRoot(window);
|
| -}
|
| -
|
| -bool WindowTree::IsWindowKnownForAccessPolicy(
|
| - const ServerWindow* window) const {
|
| - return IsWindowKnown(window);
|
| -}
|
| -
|
| -bool WindowTree::IsWindowRootOfAnotherTreeForAccessPolicy(
|
| - const ServerWindow* window) const {
|
| - WindowTree* tree = window_server_->GetTreeWithRoot(window);
|
| - return tree && tree != this;
|
| -}
|
| -
|
| -} // namespace ws
|
| -} // namespace mus
|
|
|