Index: components/mus/ws/focus_controller.cc |
diff --git a/components/mus/ws/focus_controller.cc b/components/mus/ws/focus_controller.cc |
deleted file mode 100644 |
index 5728acbe15455987b36c1dd15142cfae222c9ae4..0000000000000000000000000000000000000000 |
--- a/components/mus/ws/focus_controller.cc |
+++ /dev/null |
@@ -1,311 +0,0 @@ |
-// Copyright 2015 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/focus_controller.h" |
- |
-#include "base/macros.h" |
-#include "components/mus/public/interfaces/window_manager.mojom.h" |
-#include "components/mus/ws/focus_controller_delegate.h" |
-#include "components/mus/ws/focus_controller_observer.h" |
-#include "components/mus/ws/server_window.h" |
-#include "components/mus/ws/server_window_drawn_tracker.h" |
- |
-namespace mus { |
-namespace ws { |
- |
-namespace { |
- |
-ServerWindow* GetDeepestLastDescendant(ServerWindow* window) { |
- while (!window->children().empty()) |
- window = window->children().back(); |
- return window; |
-} |
- |
-// This can be used to iterate over each node in a rooted tree for the purpose |
-// of shifting focus/activation. |
-class WindowTreeIterator { |
- public: |
- explicit WindowTreeIterator(ServerWindow* root) : root_(root) {} |
- ~WindowTreeIterator() {} |
- |
- ServerWindow* GetNext(ServerWindow* window) const { |
- if (window == root_ || window == nullptr) |
- return GetDeepestLastDescendant(root_); |
- |
- // Return the next sibling. |
- ServerWindow* parent = window->parent(); |
- if (parent) { |
- const ServerWindow::Windows& siblings = parent->children(); |
- ServerWindow::Windows::const_reverse_iterator iter = |
- std::find(siblings.rbegin(), siblings.rend(), window); |
- DCHECK(iter != siblings.rend()); |
- ++iter; |
- if (iter != siblings.rend()) |
- return GetDeepestLastDescendant(*iter); |
- } |
- |
- // All children and siblings have been explored. Next is the parent. |
- return parent; |
- } |
- |
- private: |
- ServerWindow* root_; |
- |
- DISALLOW_COPY_AND_ASSIGN(WindowTreeIterator); |
-}; |
- |
-} // namespace |
- |
-FocusController::FocusController(FocusControllerDelegate* delegate, |
- ServerWindow* root) |
- : delegate_(delegate), |
- root_(root), |
- focused_window_(nullptr), |
- active_window_(nullptr), |
- activation_reason_(ActivationChangeReason::UNKNONW) { |
- DCHECK(delegate_); |
- DCHECK(root_); |
-} |
- |
-FocusController::~FocusController() { |
-} |
- |
-bool FocusController::SetFocusedWindow(ServerWindow* window) { |
- if (GetFocusedWindow() == window) |
- return true; |
- |
- return SetFocusedWindowImpl(FocusControllerChangeSource::EXPLICIT, window); |
-} |
- |
-ServerWindow* FocusController::GetFocusedWindow() { |
- return focused_window_; |
-} |
- |
-void FocusController::ActivateNextWindow() { |
- WindowTreeIterator iter(root_); |
- ServerWindow* activate = active_window_; |
- while (true) { |
- activate = iter.GetNext(activate); |
- if (activation_reason_ == ActivationChangeReason::CYCLE) { |
- if (activate == active_window_) { |
- // We have cycled over all the activatable windows. Remove the oldest |
- // window that was cycled. |
- if (!cycle_windows_->windows().empty()) { |
- cycle_windows_->Remove(cycle_windows_->windows().front()); |
- continue; |
- } |
- } else if (cycle_windows_->Contains(activate)) { |
- // We are cycling between activated windows, and this window has already |
- // been through the cycle. So skip over it. |
- continue; |
- } |
- } |
- if (activate == active_window_ || CanBeActivated(activate)) |
- break; |
- } |
- SetActiveWindow(activate, ActivationChangeReason::CYCLE); |
- |
- if (active_window_) { |
- // Do not shift focus if the focused window already lives in the active |
- // window. |
- if (focused_window_ && active_window_->Contains(focused_window_)) |
- return; |
- // Focus the first focusable window in the tree. |
- WindowTreeIterator iter(active_window_); |
- ServerWindow* focus = nullptr; |
- do { |
- focus = iter.GetNext(focus); |
- } while (focus != active_window_ && !CanBeFocused(focus)); |
- SetFocusedWindow(focus); |
- } else { |
- SetFocusedWindow(nullptr); |
- } |
-} |
- |
-void FocusController::AddObserver(FocusControllerObserver* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void FocusController::RemoveObserver(FocusControllerObserver* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
-void FocusController::SetActiveWindow(ServerWindow* window, |
- ActivationChangeReason reason) { |
- DCHECK(!window || CanBeActivated(window)); |
- if (active_window_ == window) |
- return; |
- if (reason != ActivationChangeReason::CYCLE) { |
- cycle_windows_.reset(); |
- } else if (activation_reason_ != ActivationChangeReason::CYCLE) { |
- DCHECK(!cycle_windows_); |
- cycle_windows_.reset(new ServerWindowTracker()); |
- if (active_window_) |
- cycle_windows_->Add(active_window_); |
- } |
- |
- ServerWindow* old_active = active_window_; |
- active_window_ = window; |
- activation_reason_ = reason; |
- FOR_EACH_OBSERVER(FocusControllerObserver, observers_, |
- OnActivationChanged(old_active, active_window_)); |
- if (active_window_ && activation_reason_ == ActivationChangeReason::CYCLE) |
- cycle_windows_->Add(active_window_); |
-} |
- |
-bool FocusController::CanBeFocused(ServerWindow* window) const { |
- // All ancestors of |window| must be drawn, and be focusable. |
- for (ServerWindow* w = window; w; w = w->parent()) { |
- if (!w->IsDrawn()) |
- return false; |
- if (!w->can_focus()) |
- return false; |
- } |
- |
- // |window| must be a descendent of an activatable window. |
- return GetActivatableAncestorOf(window) != nullptr; |
-} |
- |
-bool FocusController::CanBeActivated(ServerWindow* window) const { |
- DCHECK(window); |
- // A detached window cannot be activated. |
- if (!root_->Contains(window)) |
- return false; |
- |
- // The parent window must be allowed to have active children. |
- if (!delegate_->CanHaveActiveChildren(window->parent())) |
- return false; |
- |
- if (!window->can_focus()) |
- return false; |
- |
- // The window must be drawn, or if it's not drawn, it must be minimized. |
- if (!window->IsDrawn()) { |
- bool is_minimized = false; |
- const ServerWindow::Properties& props = window->properties(); |
- if (props.count(mojom::WindowManager::kShowState_Property)) { |
- is_minimized = |
- props.find(mojom::WindowManager::kShowState_Property)->second[0] == |
- static_cast<int>(mus::mojom::ShowState::MINIMIZED); |
- } |
- if (!is_minimized) |
- return false; |
- } |
- |
- // TODO(sad): If there's a transient modal window, then this cannot be |
- // activated. |
- return true; |
-} |
- |
-ServerWindow* FocusController::GetActivatableAncestorOf( |
- ServerWindow* window) const { |
- for (ServerWindow* w = window; w; w = w->parent()) { |
- if (CanBeActivated(w)) |
- return w; |
- } |
- return nullptr; |
-} |
- |
-bool FocusController::SetFocusedWindowImpl( |
- FocusControllerChangeSource change_source, |
- ServerWindow* window) { |
- if (window && !CanBeFocused(window)) |
- return false; |
- |
- ServerWindow* old_focused = GetFocusedWindow(); |
- |
- DCHECK(!window || window->IsDrawn()); |
- |
- // Activate the closest activatable ancestor window. |
- // TODO(sad): The window to activate doesn't necessarily have to be a direct |
- // ancestor (e.g. could be a transient parent). |
- SetActiveWindow(GetActivatableAncestorOf(window), |
- ActivationChangeReason::FOCUS); |
- |
- FOR_EACH_OBSERVER(FocusControllerObserver, observers_, |
- OnFocusChanged(change_source, old_focused, window)); |
- |
- focused_window_ = window; |
- // We can currently use only a single ServerWindowDrawnTracker since focused |
- // window is expected to be a direct descendant of the active window. |
- if (focused_window_ && active_window_) { |
- DCHECK(active_window_->Contains(focused_window_)); |
- } |
- ServerWindow* track_window = focused_window_; |
- if (!track_window) |
- track_window = active_window_; |
- if (track_window) |
- drawn_tracker_.reset(new ServerWindowDrawnTracker(track_window, this)); |
- else |
- drawn_tracker_.reset(); |
- return true; |
-} |
- |
-void FocusController::OnDrawnStateWillChange(ServerWindow* ancestor, |
- ServerWindow* window, |
- bool is_drawn) { |
- DCHECK(!is_drawn); |
- DCHECK_NE(ancestor, window); |
- DCHECK(root_->Contains(window)); |
- drawn_tracker_.reset(); |
- |
- // Find the window that triggered this state-change notification. |
- ServerWindow* trigger = window; |
- while (trigger->parent() != ancestor) |
- trigger = trigger->parent(); |
- DCHECK(trigger); |
- auto will_be_hidden = [trigger](ServerWindow* w) { |
- return trigger->Contains(w); |
- }; |
- |
- // If |window| is |active_window_|, then activate the next activatable window |
- // that does not belong to the subtree which is getting hidden. |
- if (window == active_window_) { |
- WindowTreeIterator iter(root_); |
- ServerWindow* activate = active_window_; |
- do { |
- activate = iter.GetNext(activate); |
- } while (activate != active_window_ && |
- (will_be_hidden(activate) || !CanBeActivated(activate))); |
- if (activate == window) |
- activate = nullptr; |
- SetActiveWindow(activate, ActivationChangeReason::DRAWN_STATE_CHANGED); |
- |
- // Now make sure focus is in the active window. |
- ServerWindow* focus = nullptr; |
- if (active_window_) { |
- WindowTreeIterator iter(active_window_); |
- focus = nullptr; |
- do { |
- focus = iter.GetNext(focus); |
- } while (focus != active_window_ && |
- (will_be_hidden(focus) || !CanBeFocused(focus))); |
- DCHECK(focus && CanBeFocused(focus)); |
- } |
- SetFocusedWindowImpl(FocusControllerChangeSource::DRAWN_STATE_CHANGED, |
- focus); |
- return; |
- } |
- |
- // Move focus to the next focusable window in |active_window_|. |
- DCHECK_EQ(focused_window_, window); |
- WindowTreeIterator iter(active_window_); |
- ServerWindow* focus = focused_window_; |
- do { |
- focus = iter.GetNext(focus); |
- } while (focus != focused_window_ && |
- (will_be_hidden(focus) || !CanBeFocused(focus))); |
- if (focus == window) |
- focus = nullptr; |
- SetFocusedWindowImpl(FocusControllerChangeSource::DRAWN_STATE_CHANGED, focus); |
-} |
- |
-void FocusController::OnDrawnStateChanged(ServerWindow* ancestor, |
- ServerWindow* window, |
- bool is_drawn) { |
- // DCHECK(false); TODO(sadrul): |
-} |
- |
-} // namespace ws |
-} // namespace mus |