| Index: components/mus/ws/window_manager_state.cc
|
| diff --git a/components/mus/ws/window_manager_state.cc b/components/mus/ws/window_manager_state.cc
|
| deleted file mode 100644
|
| index b394514bef2b48bec9404fae185ebc6d8b9af0fc..0000000000000000000000000000000000000000
|
| --- a/components/mus/ws/window_manager_state.cc
|
| +++ /dev/null
|
| @@ -1,485 +0,0 @@
|
| -// Copyright 2016 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_manager_state.h"
|
| -
|
| -#include "base/memory/weak_ptr.h"
|
| -#include "components/mus/common/event_matcher_util.h"
|
| -#include "components/mus/ws/accelerator.h"
|
| -#include "components/mus/ws/display_manager.h"
|
| -#include "components/mus/ws/platform_display.h"
|
| -#include "components/mus/ws/server_window.h"
|
| -#include "components/mus/ws/user_display_manager.h"
|
| -#include "components/mus/ws/user_id_tracker.h"
|
| -#include "components/mus/ws/window_manager_display_root.h"
|
| -#include "components/mus/ws/window_server.h"
|
| -#include "components/mus/ws/window_tree.h"
|
| -#include "services/shell/public/interfaces/connector.mojom.h"
|
| -#include "ui/events/event.h"
|
| -
|
| -namespace mus {
|
| -namespace ws {
|
| -namespace {
|
| -
|
| -// Debug accelerator IDs start far above the highest valid Windows command ID
|
| -// (0xDFFF) and Chrome's highest IDC command ID.
|
| -const uint32_t kPrintWindowsDebugAcceleratorId = 1u << 31;
|
| -
|
| -base::TimeDelta GetDefaultAckTimerDelay() {
|
| -#if defined(NDEBUG)
|
| - return base::TimeDelta::FromMilliseconds(100);
|
| -#else
|
| - return base::TimeDelta::FromMilliseconds(1000);
|
| -#endif
|
| -}
|
| -
|
| -bool EventsCanBeCoalesced(const ui::Event& one, const ui::Event& two) {
|
| - if (one.type() != two.type() || one.flags() != two.flags())
|
| - return false;
|
| -
|
| - // TODO(sad): wheel events can also be merged.
|
| - if (one.type() != ui::ET_POINTER_MOVED)
|
| - return false;
|
| -
|
| - return one.AsPointerEvent()->pointer_id() ==
|
| - two.AsPointerEvent()->pointer_id();
|
| -}
|
| -
|
| -std::unique_ptr<ui::Event> CoalesceEvents(std::unique_ptr<ui::Event> first,
|
| - std::unique_ptr<ui::Event> second) {
|
| - DCHECK(first->type() == ui::ET_POINTER_MOVED)
|
| - << " Non-move events cannot be merged yet.";
|
| - // For mouse moves, the new event just replaces the old event.
|
| - return second;
|
| -}
|
| -
|
| -const ServerWindow* GetEmbedRoot(const ServerWindow* window) {
|
| - DCHECK(window);
|
| - const ServerWindow* embed_root = window->parent();
|
| - while (embed_root && embed_root->id().client_id == window->id().client_id)
|
| - embed_root = embed_root->parent();
|
| - return embed_root;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -class WindowManagerState::ProcessedEventTarget {
|
| - public:
|
| - ProcessedEventTarget(ServerWindow* window,
|
| - ClientSpecificId client_id,
|
| - Accelerator* accelerator)
|
| - : client_id_(client_id) {
|
| - tracker_.Add(window);
|
| - if (accelerator)
|
| - accelerator_ = accelerator->GetWeakPtr();
|
| - }
|
| -
|
| - ~ProcessedEventTarget() {}
|
| -
|
| - // Return true if the event is still valid. The event becomes invalid if
|
| - // the window is destroyed while waiting to dispatch.
|
| - bool IsValid() const { return !tracker_.windows().empty(); }
|
| -
|
| - ServerWindow* window() {
|
| - DCHECK(IsValid());
|
| - return tracker_.windows().front();
|
| - }
|
| -
|
| - ClientSpecificId client_id() const { return client_id_; }
|
| -
|
| - base::WeakPtr<Accelerator> accelerator() { return accelerator_; }
|
| -
|
| - private:
|
| - ServerWindowTracker tracker_;
|
| - const ClientSpecificId client_id_;
|
| - base::WeakPtr<Accelerator> accelerator_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ProcessedEventTarget);
|
| -};
|
| -
|
| -WindowManagerState::QueuedEvent::QueuedEvent() {}
|
| -WindowManagerState::QueuedEvent::~QueuedEvent() {}
|
| -
|
| -WindowManagerState::WindowManagerState(WindowTree* window_tree)
|
| - : window_tree_(window_tree), event_dispatcher_(this), weak_factory_(this) {
|
| - frame_decoration_values_ = mojom::FrameDecorationValues::New();
|
| - frame_decoration_values_->max_title_bar_button_width = 0u;
|
| -
|
| - AddDebugAccelerators();
|
| -}
|
| -
|
| -WindowManagerState::~WindowManagerState() {}
|
| -
|
| -void WindowManagerState::SetFrameDecorationValues(
|
| - mojom::FrameDecorationValuesPtr values) {
|
| - got_frame_decoration_values_ = true;
|
| - frame_decoration_values_ = values.Clone();
|
| - display_manager()
|
| - ->GetUserDisplayManager(user_id())
|
| - ->OnFrameDecorationValuesChanged();
|
| -}
|
| -
|
| -bool WindowManagerState::SetCapture(ServerWindow* window,
|
| - ClientSpecificId client_id) {
|
| - DCHECK(IsActive());
|
| - if (capture_window() == window &&
|
| - client_id == event_dispatcher_.capture_window_client_id()) {
|
| - return true;
|
| - }
|
| -#if !defined(NDEBUG)
|
| - if (window) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - display_manager()->GetWindowManagerDisplayRoot(window);
|
| - DCHECK(display_root && display_root->window_manager_state() == this);
|
| - }
|
| -#endif
|
| - return event_dispatcher_.SetCaptureWindow(window, client_id);
|
| -}
|
| -
|
| -void WindowManagerState::ReleaseCaptureBlockedByModalWindow(
|
| - const ServerWindow* modal_window) {
|
| - event_dispatcher_.ReleaseCaptureBlockedByModalWindow(modal_window);
|
| -}
|
| -
|
| -void WindowManagerState::ReleaseCaptureBlockedByAnyModalWindow() {
|
| - event_dispatcher_.ReleaseCaptureBlockedByAnyModalWindow();
|
| -}
|
| -
|
| -void WindowManagerState::AddSystemModalWindow(ServerWindow* window) {
|
| - DCHECK(!window->transient_parent());
|
| - event_dispatcher_.AddSystemModalWindow(window);
|
| -}
|
| -
|
| -const UserId& WindowManagerState::user_id() const {
|
| - return window_tree_->user_id();
|
| -}
|
| -
|
| -void WindowManagerState::OnWillDestroyTree(WindowTree* tree) {
|
| - if (tree_awaiting_input_ack_ != tree)
|
| - return;
|
| -
|
| - // The WindowTree is dying. So it's not going to ack the event.
|
| - // If the dying tree matches the root |tree_| marked as handled so we don't
|
| - // notify it of accelerators.
|
| - OnEventAck(tree_awaiting_input_ack_, tree == window_tree_
|
| - ? mojom::EventResult::HANDLED
|
| - : mojom::EventResult::UNHANDLED);
|
| -}
|
| -
|
| -bool WindowManagerState::IsActive() const {
|
| - return window_server()->user_id_tracker()->active_id() == user_id();
|
| -}
|
| -
|
| -void WindowManagerState::Activate(const gfx::Point& mouse_location_on_screen) {
|
| - SetAllRootWindowsVisible(true);
|
| - event_dispatcher_.Reset();
|
| - event_dispatcher_.SetMousePointerScreenLocation(mouse_location_on_screen);
|
| -}
|
| -
|
| -void WindowManagerState::Deactivate() {
|
| - SetAllRootWindowsVisible(false);
|
| - event_dispatcher_.Reset();
|
| - // The tree is no longer active, so no point in dispatching any further
|
| - // events.
|
| - std::queue<std::unique_ptr<QueuedEvent>> event_queue;
|
| - event_queue.swap(event_queue_);
|
| -}
|
| -
|
| -void WindowManagerState::ProcessEvent(const ui::Event& event) {
|
| - // If this is still waiting for an ack from a previously sent event, then
|
| - // queue up the event to be dispatched once the ack is received.
|
| - if (event_ack_timer_.IsRunning()) {
|
| - if (!event_queue_.empty() && !event_queue_.back()->processed_target &&
|
| - EventsCanBeCoalesced(*event_queue_.back()->event, event)) {
|
| - event_queue_.back()->event = CoalesceEvents(
|
| - std::move(event_queue_.back()->event), ui::Event::Clone(event));
|
| - return;
|
| - }
|
| - QueueEvent(event, nullptr);
|
| - return;
|
| - }
|
| - event_dispatcher_.ProcessEvent(event);
|
| -}
|
| -
|
| -void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
|
| - mojom::EventResult result) {
|
| - if (tree_awaiting_input_ack_ != tree) {
|
| - // TODO(sad): The ack must have arrived after the timeout. We should do
|
| - // something here, and in OnEventAckTimeout().
|
| - return;
|
| - }
|
| - tree_awaiting_input_ack_ = nullptr;
|
| - event_ack_timer_.Stop();
|
| -
|
| - if (result == mojom::EventResult::UNHANDLED && post_target_accelerator_)
|
| - OnAccelerator(post_target_accelerator_->id(), *event_awaiting_input_ack_);
|
| -
|
| - ProcessNextEventFromQueue();
|
| -}
|
| -
|
| -const WindowServer* WindowManagerState::window_server() const {
|
| - return window_tree_->window_server();
|
| -}
|
| -
|
| -WindowServer* WindowManagerState::window_server() {
|
| - return window_tree_->window_server();
|
| -}
|
| -
|
| -DisplayManager* WindowManagerState::display_manager() {
|
| - return window_tree_->display_manager();
|
| -}
|
| -
|
| -const DisplayManager* WindowManagerState::display_manager() const {
|
| - return window_tree_->display_manager();
|
| -}
|
| -
|
| -void WindowManagerState::SetAllRootWindowsVisible(bool value) {
|
| - for (Display* display : display_manager()->displays()) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - display->GetWindowManagerDisplayRootForUser(user_id());
|
| - if (display_root)
|
| - display_root->root()->SetVisible(value);
|
| - }
|
| -}
|
| -
|
| -ServerWindow* WindowManagerState::GetWindowManagerRoot(ServerWindow* window) {
|
| - for (Display* display : display_manager()->displays()) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - display->GetWindowManagerDisplayRootForUser(user_id());
|
| - if (display_root && display_root->root()->parent() == window)
|
| - return display_root->root();
|
| - }
|
| - NOTREACHED();
|
| - return nullptr;
|
| -}
|
| -
|
| -void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) {
|
| - WindowTree* hung_tree = window_server()->GetTreeWithId(client_id);
|
| - if (hung_tree && !hung_tree->janky())
|
| - window_tree_->ClientJankinessChanged(hung_tree);
|
| - OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED);
|
| -}
|
| -
|
| -void WindowManagerState::QueueEvent(
|
| - const ui::Event& event,
|
| - std::unique_ptr<ProcessedEventTarget> processed_event_target) {
|
| - std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent);
|
| - queued_event->event = ui::Event::Clone(event);
|
| - queued_event->processed_target = std::move(processed_event_target);
|
| - event_queue_.push(std::move(queued_event));
|
| -}
|
| -
|
| -void WindowManagerState::ProcessNextEventFromQueue() {
|
| - // Loop through |event_queue_| stopping after dispatching the first valid
|
| - // event.
|
| - while (!event_queue_.empty()) {
|
| - std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
|
| - event_queue_.pop();
|
| - if (!queued_event->processed_target) {
|
| - event_dispatcher_.ProcessEvent(*queued_event->event);
|
| - return;
|
| - }
|
| - if (queued_event->processed_target->IsValid()) {
|
| - DispatchInputEventToWindowImpl(
|
| - queued_event->processed_target->window(),
|
| - queued_event->processed_target->client_id(), *queued_event->event,
|
| - queued_event->processed_target->accelerator());
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WindowManagerState::DispatchInputEventToWindowImpl(
|
| - ServerWindow* target,
|
| - ClientSpecificId client_id,
|
| - const ui::Event& event,
|
| - base::WeakPtr<Accelerator> accelerator) {
|
| - if (target && target->parent() == nullptr)
|
| - target = GetWindowManagerRoot(target);
|
| -
|
| - if (event.IsMousePointerEvent()) {
|
| - DCHECK(event_dispatcher_.mouse_cursor_source_window());
|
| -
|
| - int32_t cursor_id = 0;
|
| - if (event_dispatcher_.GetCurrentMouseCursor(&cursor_id)) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - display_manager()->GetWindowManagerDisplayRoot(target);
|
| - display_root->display()->UpdateNativeCursor(cursor_id);
|
| - }
|
| - }
|
| -
|
| - WindowTree* tree = window_server()->GetTreeWithId(client_id);
|
| -
|
| - // TOOD(sad): Adjust this delay, possibly make this dynamic.
|
| - const base::TimeDelta max_delay = base::debug::BeingDebugged()
|
| - ? base::TimeDelta::FromDays(1)
|
| - : GetDefaultAckTimerDelay();
|
| - event_ack_timer_.Start(
|
| - FROM_HERE, max_delay,
|
| - base::Bind(&WindowManagerState::OnEventAckTimeout,
|
| - weak_factory_.GetWeakPtr(), tree->id()));
|
| -
|
| - tree_awaiting_input_ack_ = tree;
|
| - if (accelerator) {
|
| - event_awaiting_input_ack_ = ui::Event::Clone(event);
|
| - post_target_accelerator_ = accelerator;
|
| - }
|
| -
|
| - // Ignore |tree| because it will receive the event via normal dispatch.
|
| - window_server()->SendToEventObservers(event, user_id(), tree);
|
| -
|
| - tree->DispatchInputEvent(target, event);
|
| -}
|
| -
|
| -void WindowManagerState::AddDebugAccelerators() {
|
| - // Always register the accelerators, even if they only work in debug, so that
|
| - // keyboard behavior is the same in release and debug builds.
|
| - mojom::EventMatcherPtr matcher = CreateKeyMatcher(
|
| - ui::mojom::KeyboardCode::S, ui::mojom::kEventFlagControlDown |
|
| - ui::mojom::kEventFlagAltDown |
|
| - ui::mojom::kEventFlagShiftDown);
|
| - event_dispatcher_.AddAccelerator(kPrintWindowsDebugAcceleratorId,
|
| - std::move(matcher));
|
| -}
|
| -
|
| -bool WindowManagerState::HandleDebugAccelerator(uint32_t accelerator_id) {
|
| -#if !defined(NDEBUG)
|
| - if (accelerator_id == kPrintWindowsDebugAcceleratorId) {
|
| - // Error so it will be collected in system logs.
|
| - for (Display* display : display_manager()->displays()) {
|
| - WindowManagerDisplayRoot* display_root =
|
| - display->GetWindowManagerDisplayRootForUser(user_id());
|
| - if (display_root) {
|
| - LOG(ERROR) << "ServerWindow hierarchy:\n"
|
| - << display_root->root()->GetDebugWindowHierarchy();
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -#endif
|
| - return false;
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// EventDispatcherDelegate:
|
| -
|
| -void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
|
| - const ui::Event& event) {
|
| - DCHECK(IsActive());
|
| - if (HandleDebugAccelerator(accelerator_id))
|
| - return;
|
| - window_tree_->OnAccelerator(accelerator_id, event);
|
| -}
|
| -
|
| -void WindowManagerState::SetFocusedWindowFromEventDispatcher(
|
| - ServerWindow* new_focused_window) {
|
| - DCHECK(IsActive());
|
| - window_server()->SetFocusedWindow(new_focused_window);
|
| -}
|
| -
|
| -ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher() {
|
| - return window_server()->GetFocusedWindow();
|
| -}
|
| -
|
| -void WindowManagerState::SetNativeCapture(ServerWindow* window) {
|
| - DCHECK(IsActive());
|
| - WindowManagerDisplayRoot* display_root =
|
| - display_manager()->GetWindowManagerDisplayRoot(window);
|
| - DCHECK(display_root);
|
| - platform_display_with_capture_ = display_root->display()->platform_display();
|
| - platform_display_with_capture_->SetCapture();
|
| -}
|
| -
|
| -void WindowManagerState::ReleaseNativeCapture() {
|
| - // Tests trigger calling this without a corresponding SetNativeCapture().
|
| - // TODO(sky): maybe abstract this away so that DCHECK can be added?
|
| - if (!platform_display_with_capture_)
|
| - return;
|
| -
|
| - platform_display_with_capture_->ReleaseCapture();
|
| - platform_display_with_capture_ = nullptr;
|
| -}
|
| -
|
| -void WindowManagerState::OnServerWindowCaptureLost(ServerWindow* window) {
|
| - DCHECK(window);
|
| - window_server()->ProcessLostCapture(window);
|
| -}
|
| -
|
| -void WindowManagerState::OnMouseCursorLocationChanged(const gfx::Point& point) {
|
| - window_server()
|
| - ->display_manager()
|
| - ->GetUserDisplayManager(user_id())
|
| - ->OnMouseCursorLocationChanged(point);
|
| -}
|
| -
|
| -void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target,
|
| - ClientSpecificId client_id,
|
| - const ui::Event& event,
|
| - Accelerator* accelerator) {
|
| - DCHECK(IsActive());
|
| - // TODO(sky): this needs to see if another wms has capture and if so forward
|
| - // to it.
|
| - if (event_ack_timer_.IsRunning()) {
|
| - std::unique_ptr<ProcessedEventTarget> processed_event_target(
|
| - new ProcessedEventTarget(target, client_id, accelerator));
|
| - QueueEvent(event, std::move(processed_event_target));
|
| - return;
|
| - }
|
| -
|
| - base::WeakPtr<Accelerator> weak_accelerator;
|
| - if (accelerator)
|
| - weak_accelerator = accelerator->GetWeakPtr();
|
| - DispatchInputEventToWindowImpl(target, client_id, event, weak_accelerator);
|
| -}
|
| -
|
| -ClientSpecificId WindowManagerState::GetEventTargetClientId(
|
| - const ServerWindow* window,
|
| - bool in_nonclient_area) {
|
| - // If the event is in the non-client area the event goes to the owner of
|
| - // the window.
|
| - WindowTree* tree = nullptr;
|
| - if (in_nonclient_area) {
|
| - tree = window_server()->GetTreeWithId(window->id().client_id);
|
| - } else {
|
| - // If the window is an embed root, forward to the embedded window.
|
| - tree = window_server()->GetTreeWithRoot(window);
|
| - if (!tree)
|
| - tree = window_server()->GetTreeWithId(window->id().client_id);
|
| - }
|
| -
|
| - const ServerWindow* embed_root =
|
| - tree->HasRoot(window) ? window : GetEmbedRoot(window);
|
| - while (tree && tree->embedder_intercepts_events()) {
|
| - DCHECK(tree->HasRoot(embed_root));
|
| - tree = window_server()->GetTreeWithId(embed_root->id().client_id);
|
| - embed_root = GetEmbedRoot(embed_root);
|
| - }
|
| -
|
| - if (!tree) {
|
| - DCHECK(in_nonclient_area);
|
| - tree = window_tree_;
|
| - }
|
| - return tree->id();
|
| -}
|
| -
|
| -ServerWindow* WindowManagerState::GetRootWindowContaining(
|
| - const gfx::Point& location) {
|
| - if (display_manager()->displays().empty())
|
| - return nullptr;
|
| -
|
| - // TODO(sky): this isn't right. To correctly implement need bounds of
|
| - // Display, which we aren't tracking yet. For now, use the first display.
|
| - Display* display = *(display_manager()->displays().begin());
|
| - WindowManagerDisplayRoot* display_root =
|
| - display->GetWindowManagerDisplayRootForUser(user_id());
|
| - return display_root ? display_root->root() : nullptr;
|
| -}
|
| -
|
| -void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) {
|
| - window_server()->SendToEventObservers(event, user_id(),
|
| - nullptr /* ignore_tree */);
|
| -}
|
| -
|
| -} // namespace ws
|
| -} // namespace mus
|
|
|