| 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 "ui/views/corewm/base_focus_rules.h" | 5 #include "ui/views/corewm/base_focus_rules.h" |
| 6 | 6 |
| 7 #include "ui/aura/client/activation_delegate.h" | 7 #include "ui/aura/client/activation_delegate.h" |
| 8 #include "ui/aura/client/focus_client.h" | 8 #include "ui/aura/client/focus_client.h" |
| 9 #include "ui/aura/root_window.h" | 9 #include "ui/aura/root_window.h" |
| 10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 // The window must be visible. | 62 // The window must be visible. |
| 63 if (!IsWindowConsideredVisibleForActivation(window)) | 63 if (!IsWindowConsideredVisibleForActivation(window)) |
| 64 return false; | 64 return false; |
| 65 | 65 |
| 66 // The window's activation delegate must allow this window to be activated. | 66 // The window's activation delegate must allow this window to be activated. |
| 67 if (aura::client::GetActivationDelegate(window) && | 67 if (aura::client::GetActivationDelegate(window) && |
| 68 !aura::client::GetActivationDelegate(window)->ShouldActivate()) { | 68 !aura::client::GetActivationDelegate(window)->ShouldActivate()) { |
| 69 return false; | 69 return false; |
| 70 } | 70 } |
| 71 | 71 |
| 72 // A window must be focusable to be activatable. We don't call |
| 73 // CanFocusWindow() from here because it will call back to us via |
| 74 // GetActivatableWindow(). |
| 75 if (!window->CanFocus()) |
| 76 return false; |
| 77 |
| 72 // The window cannot be blocked by a modal transient. | 78 // The window cannot be blocked by a modal transient. |
| 73 return !GetModalTransient(window); | 79 return !GetModalTransient(window); |
| 74 } | 80 } |
| 75 | 81 |
| 76 bool BaseFocusRules::CanFocusWindow(aura::Window* window) const { | 82 bool BaseFocusRules::CanFocusWindow(aura::Window* window) const { |
| 77 // It is possible to focus a NULL window, it is equivalent to clearing focus. | 83 // It is possible to focus a NULL window, it is equivalent to clearing focus. |
| 78 if (!window) | 84 if (!window) |
| 79 return true; | 85 return true; |
| 80 | 86 |
| 81 // The focused window is always inside the active window, so windows that | 87 // The focused window is always inside the active window, so windows that |
| (...skipping 17 matching lines...) Expand all Loading... |
| 99 return NULL; | 105 return NULL; |
| 100 } | 106 } |
| 101 | 107 |
| 102 aura::Window* BaseFocusRules::GetActivatableWindow(aura::Window* window) const { | 108 aura::Window* BaseFocusRules::GetActivatableWindow(aura::Window* window) const { |
| 103 aura::Window* parent = window->parent(); | 109 aura::Window* parent = window->parent(); |
| 104 aura::Window* child = window; | 110 aura::Window* child = window; |
| 105 while (parent) { | 111 while (parent) { |
| 106 if (CanActivateWindow(child)) | 112 if (CanActivateWindow(child)) |
| 107 return child; | 113 return child; |
| 108 | 114 |
| 115 // CanActivateWindow() above will return false if |child| is blocked by a |
| 116 // modal transient. In this case the modal is or contains the activatable |
| 117 // window. We recurse because the modal may itself be blocked by a modal |
| 118 // transient. |
| 119 aura::Window* modal_transient = GetModalTransient(child); |
| 120 if (modal_transient) |
| 121 return GetActivatableWindow(modal_transient); |
| 122 |
| 109 if (child->transient_parent()) | 123 if (child->transient_parent()) |
| 110 return GetActivatableWindow(child->transient_parent()); | 124 return GetActivatableWindow(child->transient_parent()); |
| 111 | 125 |
| 112 parent = parent->parent(); | 126 parent = parent->parent(); |
| 113 child = child->parent(); | 127 child = child->parent(); |
| 114 } | 128 } |
| 115 return NULL; | 129 return NULL; |
| 116 } | 130 } |
| 117 | 131 |
| 118 aura::Window* BaseFocusRules::GetFocusableWindow(aura::Window* window) const { | 132 aura::Window* BaseFocusRules::GetFocusableWindow(aura::Window* window) const { |
| 119 if (CanFocusWindow(window)) | 133 if (CanFocusWindow(window)) |
| 120 return window; | 134 return window; |
| 121 | 135 |
| 122 // |window| may be in a hierarchy that is non-activatable, in which case we | 136 // |window| may be in a hierarchy that is non-activatable, in which case we |
| 123 // need to cut over to the activatable hierarchy. | 137 // need to cut over to the activatable hierarchy. |
| 124 aura::Window* activatable = GetActivatableWindow(window); | 138 aura::Window* activatable = GetActivatableWindow(window); |
| 125 if (!activatable) | 139 if (!activatable) { |
| 126 return GetFocusedWindow(window); | 140 // There may not be a related activatable hierarchy to cut over to, in which |
| 141 // case we try an unrelated one. |
| 142 aura::Window* toplevel = GetToplevelWindow(window); |
| 143 if (toplevel) |
| 144 activatable = GetNextActivatableWindow(toplevel); |
| 145 if (!activatable) |
| 146 return NULL; |
| 147 } |
| 127 | 148 |
| 128 if (!activatable->Contains(window)) { | 149 if (!activatable->Contains(window)) { |
| 129 // If there's already a child window focused in the activatable hierarchy, | 150 // If there's already a child window focused in the activatable hierarchy, |
| 130 // just use that (i.e. don't shift focus), otherwise we need to at least cut | 151 // just use that (i.e. don't shift focus), otherwise we need to at least cut |
| 131 // over to the activatable hierarchy. | 152 // over to the activatable hierarchy. |
| 132 aura::Window* focused = GetFocusedWindow(activatable); | 153 aura::Window* focused = GetFocusedWindow(activatable); |
| 133 return activatable->Contains(focused) ? focused : activatable; | 154 return activatable->Contains(focused) ? focused : activatable; |
| 134 } | 155 } |
| 135 | 156 |
| 136 while (window && !CanFocusWindow(window)) | 157 while (window && !CanFocusWindow(window)) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 | 190 |
| 170 // Focus cycling is currently very primitive: we just climb the tree. | 191 // Focus cycling is currently very primitive: we just climb the tree. |
| 171 // If need be, we could add the ability to look at siblings, descend etc. | 192 // If need be, we could add the ability to look at siblings, descend etc. |
| 172 // For test coverage, see FocusControllerImplicitTestBase subclasses in | 193 // For test coverage, see FocusControllerImplicitTestBase subclasses in |
| 173 // focus_controller_unittest.cc. | 194 // focus_controller_unittest.cc. |
| 174 return GetFocusableWindow(ignore->parent()); | 195 return GetFocusableWindow(ignore->parent()); |
| 175 } | 196 } |
| 176 | 197 |
| 177 } // namespace corewm | 198 } // namespace corewm |
| 178 } // namespace views | 199 } // namespace views |
| OLD | NEW |