OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/activation_controller.h" | 5 #include "ash/wm/activation_controller.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
9 #include "ash/wm/window_modality_controller.h" | 9 #include "ash/wm/window_modality_controller.h" |
10 #include "ash/wm/window_util.h" | 10 #include "ash/wm/window_util.h" |
11 #include "base/auto_reset.h" | 11 #include "base/auto_reset.h" |
12 #include "ui/aura/client/activation_delegate.h" | 12 #include "ui/aura/client/activation_delegate.h" |
13 #include "ui/aura/client/aura_constants.h" | 13 #include "ui/aura/client/aura_constants.h" |
14 #include "ui/aura/env.h" | 14 #include "ui/aura/env.h" |
15 #include "ui/aura/root_window.h" | 15 #include "ui/aura/root_window.h" |
16 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
17 #include "ui/aura/window_delegate.h" | 17 #include "ui/aura/window_delegate.h" |
18 #include "ui/base/ui_base_types.h" | 18 #include "ui/base/ui_base_types.h" |
19 | 19 |
20 namespace ash { | 20 namespace ash { |
21 namespace internal { | 21 namespace internal { |
22 namespace { | 22 namespace { |
23 | 23 |
24 // These are the list of container ids of containers which may contain windows | |
25 // that need to be activated in the order that they should be activated. | |
26 const int kWindowContainerIds[] = { | |
27 kShellWindowId_LockSystemModalContainer, | |
28 kShellWindowId_LockScreenContainer, | |
29 kShellWindowId_SystemModalContainer, | |
30 kShellWindowId_AlwaysOnTopContainer, | |
31 kShellWindowId_DefaultContainer, | |
32 | |
33 // Panel, launcher and status are intentionally checked after other | |
34 // containers even though these layers are higher. The user expects their | |
35 // windows to be focused before these elements. | |
36 kShellWindowId_PanelContainer, | |
37 kShellWindowId_LauncherContainer, | |
38 kShellWindowId_StatusContainer, | |
39 }; | |
40 | |
24 aura::Window* GetContainer(int id) { | 41 aura::Window* GetContainer(int id) { |
25 return Shell::GetInstance()->GetContainer(id); | 42 return Shell::GetInstance()->GetContainer(id); |
26 } | 43 } |
27 | 44 |
28 // Returns true if children of |window| can be activated. | 45 // Returns true if children of |window| can be activated. |
29 // These are the only containers in which windows can receive focus. | 46 // These are the only containers in which windows can receive focus. |
30 bool SupportsChildActivation(aura::Window* window) { | 47 bool SupportsChildActivation(aura::Window* window) { |
31 return window->id() == kShellWindowId_DefaultContainer || | 48 for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) { |
32 window->id() == kShellWindowId_AlwaysOnTopContainer || | 49 if (window->id() == kWindowContainerIds[i]) |
33 window->id() == kShellWindowId_PanelContainer || | 50 return true; |
34 window->id() == kShellWindowId_SystemModalContainer || | 51 } |
oshima
2012/03/02 19:08:40
I think you can use std::find, although it may no
flackr
2012/03/02 19:28:37
I'll leave it as it is, std::find looks pretty mes
| |
35 window->id() == kShellWindowId_StatusContainer || | 52 return false; |
36 window->id() == kShellWindowId_LauncherContainer || | |
37 window->id() == kShellWindowId_LockScreenContainer || | |
38 window->id() == kShellWindowId_LockSystemModalContainer; | |
39 } | 53 } |
40 | 54 |
41 // Returns true if |window| can be activated or deactivated. | 55 // Returns true if |window| can be activated or deactivated. |
42 // A window manager typically defines some notion of "top level window" that | 56 // A window manager typically defines some notion of "top level window" that |
43 // supports activation/deactivation. | 57 // supports activation/deactivation. |
44 bool CanActivateWindow(aura::Window* window) { | 58 bool CanActivateWindow(aura::Window* window) { |
45 return window && | 59 return window && |
46 window->IsVisible() && | 60 window->IsVisible() && |
47 (!aura::client::GetActivationDelegate(window) || | 61 (!aura::client::GetActivationDelegate(window) || |
48 aura::client::GetActivationDelegate(window)->ShouldActivate(NULL)) && | 62 aura::client::GetActivationDelegate(window)->ShouldActivate(NULL)) && |
(...skipping 13 matching lines...) Expand all Loading... | |
62 transient_parent = transient_parent->transient_parent(); | 76 transient_parent = transient_parent->transient_parent(); |
63 } | 77 } |
64 } | 78 } |
65 | 79 |
66 } // namespace | 80 } // namespace |
67 | 81 |
68 //////////////////////////////////////////////////////////////////////////////// | 82 //////////////////////////////////////////////////////////////////////////////// |
69 // ActivationController, public: | 83 // ActivationController, public: |
70 | 84 |
71 ActivationController::ActivationController() | 85 ActivationController::ActivationController() |
72 : updating_activation_(false), | 86 : updating_activation_(false) { |
73 default_container_for_test_(NULL) { | |
74 aura::client::SetActivationClient(Shell::GetRootWindow(), this); | 87 aura::client::SetActivationClient(Shell::GetRootWindow(), this); |
75 aura::Env::GetInstance()->AddObserver(this); | 88 aura::Env::GetInstance()->AddObserver(this); |
76 Shell::GetRootWindow()->AddRootWindowObserver(this); | 89 Shell::GetRootWindow()->AddRootWindowObserver(this); |
77 } | 90 } |
78 | 91 |
79 ActivationController::~ActivationController() { | 92 ActivationController::~ActivationController() { |
80 Shell::GetRootWindow()->RemoveRootWindowObserver(this); | 93 Shell::GetRootWindow()->RemoveRootWindowObserver(this); |
81 aura::Env::GetInstance()->RemoveObserver(this); | 94 aura::Env::GetInstance()->RemoveObserver(this); |
82 } | 95 } |
83 | 96 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 //////////////////////////////////////////////////////////////////////////////// | 214 //////////////////////////////////////////////////////////////////////////////// |
202 // ActivationController, private: | 215 // ActivationController, private: |
203 | 216 |
204 void ActivationController::ActivateNextWindow(aura::Window* window) { | 217 void ActivationController::ActivateNextWindow(aura::Window* window) { |
205 if (wm::IsActiveWindow(window)) | 218 if (wm::IsActiveWindow(window)) |
206 ActivateWindow(GetTopmostWindowToActivate(window)); | 219 ActivateWindow(GetTopmostWindowToActivate(window)); |
207 } | 220 } |
208 | 221 |
209 aura::Window* ActivationController::GetTopmostWindowToActivate( | 222 aura::Window* ActivationController::GetTopmostWindowToActivate( |
210 aura::Window* ignore) const { | 223 aura::Window* ignore) const { |
211 const aura::Window* container = | 224 size_t current_container_index = 0; |
212 default_container_for_test_ ? default_container_for_test_ : | 225 // If the container of the window losing focus is in the list, start from that |
213 GetContainer(kShellWindowId_DefaultContainer); | 226 // container. |
214 // When destructing an active window that is in a container destructed after | 227 for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) { |
oshima
2012/03/02 19:08:40
can ignore be null? if so, ignore && i < ...
flackr
2012/03/02 19:28:37
Done.
| |
215 // the default container during shell shutdown, |container| would be NULL | 228 aura::Window* container = GetContainer(kWindowContainerIds[i]); |
216 // because default container is destructed at this point. | 229 if (container && container->Contains(ignore)) { |
217 if (container) { | 230 current_container_index = i; |
218 for (aura::Window::Windows::const_reverse_iterator i = | 231 break; |
219 container->children().rbegin(); | |
220 i != container->children().rend(); | |
221 ++i) { | |
222 if (*i != ignore && CanActivateWindow(*i)) | |
223 return *i; | |
224 } | 232 } |
225 } | 233 } |
234 | |
235 // Look for windows to focus in that container and below. | |
236 aura::Window* window = NULL; | |
237 for (; !window && current_container_index < arraysize(kWindowContainerIds); | |
238 current_container_index++) { | |
oshima
2012/03/02 19:08:40
indent
flackr
2012/03/02 19:28:37
Done.
| |
239 aura::Window* container = | |
240 GetContainer(kWindowContainerIds[current_container_index]); | |
241 if (container) | |
242 window = GetTopmostWindowToActivateInContainer(container, ignore); | |
243 } | |
244 return window; | |
245 } | |
246 | |
247 aura::Window* ActivationController::GetTopmostWindowToActivateInContainer( | |
248 aura::Window* container, | |
249 aura::Window* ignore) const { | |
250 for (aura::Window::Windows::const_reverse_iterator i = | |
251 container->children().rbegin(); | |
252 i != container->children().rend(); | |
253 ++i) { | |
254 if (*i != ignore && CanActivateWindow(*i)) | |
255 return *i; | |
256 } | |
226 return NULL; | 257 return NULL; |
227 } | 258 } |
228 | 259 |
229 } // namespace internal | 260 } // namespace internal |
230 } // namespace ash | 261 } // namespace ash |
OLD | NEW |