remove cloud_storage and PageSetError from page_set.
[chromium-blink-merge.git] / ash / wm / ash_focus_rules.cc
blob12b301ac743d54349af57e44cf7454fc4c5004b7
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/ash_focus_rules.h"
7 #include "ash/session/session_state_delegate.h"
8 #include "ash/shell.h"
9 #include "ash/shell_delegate.h"
10 #include "ash/shell_window_ids.h"
11 #include "ash/wm/mru_window_tracker.h"
12 #include "ash/wm/window_state.h"
13 #include "ui/aura/window.h"
15 namespace ash {
16 namespace wm {
17 namespace {
19 // These are the list of container ids of containers which may contain windows
20 // that need to be activated in the order that they should be activated.
21 const int kWindowContainerIds[] = {
22 kShellWindowId_OverlayContainer,
23 kShellWindowId_LockSystemModalContainer,
24 kShellWindowId_SettingBubbleContainer,
25 kShellWindowId_LockScreenContainer,
26 kShellWindowId_SystemModalContainer,
27 kShellWindowId_AlwaysOnTopContainer,
28 kShellWindowId_AppListContainer,
29 kShellWindowId_DefaultContainer,
31 // Docked, panel, launcher and status are intentionally checked after other
32 // containers even though these layers are higher. The user expects their
33 // windows to be focused before these elements.
34 kShellWindowId_DockedContainer,
35 kShellWindowId_PanelContainer,
36 kShellWindowId_ShelfContainer,
37 kShellWindowId_StatusContainer, };
39 bool BelongsToContainerWithEqualOrGreaterId(const aura::Window* window,
40 int container_id) {
41 for (; window; window = window->parent()) {
42 if (window->id() >= container_id)
43 return true;
45 return false;
48 } // namespace
50 ////////////////////////////////////////////////////////////////////////////////
51 // AshFocusRules, public:
53 AshFocusRules::AshFocusRules() : is_shutting_down_(false) {
54 ash::Shell::GetInstance()->AddShellObserver(this);
57 AshFocusRules::~AshFocusRules() {
58 ash::Shell::GetInstance()->RemoveShellObserver(this);
61 bool AshFocusRules::IsWindowConsideredActivatable(aura::Window* window) const {
62 // Only toplevel windows can be activated.
63 if (!IsToplevelWindow(window))
64 return false;
66 // The window must be visible.
67 if (!IsWindowConsideredVisibleForActivation(window))
68 return false;
70 return true;
73 ////////////////////////////////////////////////////////////////////////////////
74 // AshFocusRules, ::wm::FocusRules:
76 bool AshFocusRules::SupportsChildActivation(aura::Window* window) const {
77 if (window->id() == kShellWindowId_DefaultContainer)
78 return true;
80 for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) {
81 if (window->id() == kWindowContainerIds[i])
82 return true;
84 return false;
87 bool AshFocusRules::IsWindowConsideredVisibleForActivation(
88 aura::Window* window) const {
89 // If the |window| doesn't belong to the current active user and also doesn't
90 // show for the current active user, then it should not be activated.
91 SessionStateDelegate* delegate =
92 Shell::GetInstance()->session_state_delegate();
93 if (delegate->NumberOfLoggedInUsers() > 1) {
94 content::BrowserContext* active_browser_context =
95 Shell::GetInstance()->delegate()->GetActiveBrowserContext();
96 content::BrowserContext* owner_browser_context =
97 delegate->GetBrowserContextForWindow(window);
98 content::BrowserContext* shown_browser_context =
99 delegate->GetUserPresentingBrowserContextForWindow(window);
101 if (owner_browser_context && active_browser_context &&
102 owner_browser_context != active_browser_context &&
103 shown_browser_context != active_browser_context) {
104 return false;
108 if (BaseFocusRules::IsWindowConsideredVisibleForActivation(window))
109 return true;
111 // Minimized windows are hidden in their minimized state, but they can always
112 // be activated.
113 if (wm::GetWindowState(window)->IsMinimized())
114 return true;
116 return window->TargetVisibility() &&
117 (window->parent()->id() == kShellWindowId_DefaultContainer ||
118 window->parent()->id() == kShellWindowId_LockScreenContainer);
121 bool AshFocusRules::CanActivateWindow(aura::Window* window) const {
122 // Clearing activation is always permissible.
123 if (!window)
124 return true;
126 if (!BaseFocusRules::CanActivateWindow(window))
127 return false;
129 if (Shell::GetInstance()->IsSystemModalWindowOpen()) {
130 return BelongsToContainerWithEqualOrGreaterId(
131 window, kShellWindowId_SystemModalContainer);
134 return true;
137 aura::Window* AshFocusRules::GetNextActivatableWindow(
138 aura::Window* ignore) const {
139 if (is_shutting_down_)
140 return nullptr;
142 DCHECK(ignore);
144 // Start from the container of the most-recently-used window. If the list of
145 // MRU windows is empty, then start from the container of the window that just
146 // lost focus |ignore|.
147 ash::MruWindowTracker* mru = ash::Shell::GetInstance()->mru_window_tracker();
148 std::vector<aura::Window*> windows = mru->BuildMruWindowList();
149 aura::Window* starting_window = windows.empty() ? ignore : windows[0];
151 // Look for windows to focus in |starting_window|'s container. If none are
152 // found, we look in all the containers in front of |starting_window|'s
153 // container, then all behind.
154 int starting_container_index = 0;
155 aura::Window* root = starting_window->GetRootWindow();
156 if (!root)
157 root = Shell::GetTargetRootWindow();
158 int container_count = static_cast<int>(arraysize(kWindowContainerIds));
159 for (int i = 0; i < container_count; i++) {
160 aura::Window* container = Shell::GetContainer(root, kWindowContainerIds[i]);
161 if (container && container->Contains(starting_window)) {
162 starting_container_index = i;
163 break;
167 aura::Window* window = nullptr;
168 for (int i = starting_container_index; !window && i < container_count; i++)
169 window = GetTopmostWindowToActivateForContainerIndex(i, ignore);
170 if (!window && starting_container_index > 0) {
171 for (int i = starting_container_index - 1; !window && i >= 0; i--)
172 window = GetTopmostWindowToActivateForContainerIndex(i, ignore);
174 return window;
177 ////////////////////////////////////////////////////////////////////////////////
178 // AshFocusRules, private:
180 aura::Window* AshFocusRules::GetTopmostWindowToActivateForContainerIndex(
181 int index,
182 aura::Window* ignore) const {
183 aura::Window* window = NULL;
184 aura::Window* root = ignore ? ignore->GetRootWindow() : NULL;
185 aura::Window::Windows containers = Shell::GetContainersFromAllRootWindows(
186 kWindowContainerIds[index], root);
187 for (aura::Window::Windows::const_iterator iter = containers.begin();
188 iter != containers.end() && !window; ++iter) {
189 window = GetTopmostWindowToActivateInContainer((*iter), ignore);
191 return window;
194 aura::Window* AshFocusRules::GetTopmostWindowToActivateInContainer(
195 aura::Window* container,
196 aura::Window* ignore) const {
197 for (aura::Window::Windows::const_reverse_iterator i =
198 container->children().rbegin();
199 i != container->children().rend();
200 ++i) {
201 WindowState* window_state = GetWindowState(*i);
202 if (*i != ignore &&
203 window_state->CanActivate() &&
204 !window_state->IsMinimized())
205 return *i;
207 return NULL;
210 void AshFocusRules::OnAppTerminating() {
211 is_shutting_down_ = true;
214 } // namespace wm
215 } // namespace ash