| 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/wm/core/base_focus_rules.h" | 5 #include "ui/wm/core/base_focus_rules.h" |
| 6 | 6 |
| 7 #include "ui/aura/client/focus_client.h" | 7 #include "ui/aura/client/focus_client.h" |
| 8 #include "ui/aura/window.h" | 8 #include "ui/aura/window.h" |
| 9 #include "ui/wm/core/window_modality_controller.h" | 9 #include "ui/wm/core/window_modality_controller.h" |
| 10 #include "ui/wm/core/window_util.h" | 10 #include "ui/wm/core/window_util.h" |
| 11 #include "ui/wm/public/activation_delegate.h" | 11 #include "ui/wm/public/activation_delegate.h" |
| 12 | 12 |
| 13 namespace wm { | 13 namespace wm { |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 aura::Window* GetFocusedWindow(aura::Window* context) { | 16 aura::Window* GetFocusedWindow(aura::Window* context) { |
| 17 aura::client::FocusClient* focus_client = | 17 aura::client::FocusClient* focus_client = |
| 18 aura::client::GetFocusClient(context); | 18 aura::client::GetFocusClient(context); |
| 19 return focus_client ? focus_client->GetFocusedWindow() : NULL; | 19 return focus_client ? focus_client->GetFocusedWindow() : nullptr; |
| 20 } | 20 } |
| 21 | 21 |
| 22 } // namespace | 22 } // namespace |
| 23 | 23 |
| 24 //////////////////////////////////////////////////////////////////////////////// | 24 //////////////////////////////////////////////////////////////////////////////// |
| 25 // BaseFocusRules, protected: | 25 // BaseFocusRules, protected: |
| 26 | 26 |
| 27 BaseFocusRules::BaseFocusRules() { | 27 BaseFocusRules::BaseFocusRules() = default; |
| 28 } | |
| 29 | 28 |
| 30 BaseFocusRules::~BaseFocusRules() { | 29 BaseFocusRules::~BaseFocusRules() = default; |
| 31 } | |
| 32 | 30 |
| 33 bool BaseFocusRules::IsWindowConsideredVisibleForActivation( | 31 bool BaseFocusRules::IsWindowConsideredVisibleForActivation( |
| 34 aura::Window* window) const { | 32 aura::Window* window) const { |
| 35 return window->IsVisible(); | 33 return window->IsVisible(); |
| 36 } | 34 } |
| 37 | 35 |
| 38 //////////////////////////////////////////////////////////////////////////////// | 36 //////////////////////////////////////////////////////////////////////////////// |
| 39 // BaseFocusRules, FocusRules implementation: | 37 // BaseFocusRules, FocusRules implementation: |
| 40 | 38 |
| 41 bool BaseFocusRules::IsToplevelWindow(aura::Window* window) const { | 39 bool BaseFocusRules::IsToplevelWindow(aura::Window* window) const { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 71 // A window must be focusable to be activatable. We don't call | 69 // A window must be focusable to be activatable. We don't call |
| 72 // CanFocusWindow() from here because it will call back to us via | 70 // CanFocusWindow() from here because it will call back to us via |
| 73 // GetActivatableWindow(). | 71 // GetActivatableWindow(). |
| 74 if (!window->CanFocus()) | 72 if (!window->CanFocus()) |
| 75 return false; | 73 return false; |
| 76 | 74 |
| 77 // The window cannot be blocked by a modal transient. | 75 // The window cannot be blocked by a modal transient. |
| 78 return !GetModalTransient(window); | 76 return !GetModalTransient(window); |
| 79 } | 77 } |
| 80 | 78 |
| 81 bool BaseFocusRules::CanFocusWindow(aura::Window* window) const { | 79 bool BaseFocusRules::CanFocusWindow(aura::Window* window, |
| 80 const ui::Event* event) const { |
| 82 // It is possible to focus a NULL window, it is equivalent to clearing focus. | 81 // It is possible to focus a NULL window, it is equivalent to clearing focus. |
| 83 if (!window) | 82 if (!window) |
| 84 return true; | 83 return true; |
| 85 | 84 |
| 86 // The focused window is always inside the active window, so windows that | 85 // The focused window is always inside the active window, so windows that |
| 87 // aren't activatable can't contain the focused window. | 86 // aren't activatable can't contain the focused window. |
| 88 aura::Window* activatable = GetActivatableWindow(window); | 87 aura::Window* activatable = GetActivatableWindow(window); |
| 89 if (!activatable || !activatable->Contains(window)) | 88 if (!activatable || !activatable->Contains(window)) |
| 90 return false; | 89 return false; |
| 91 return window->CanFocus(); | 90 return window->CanFocus(); |
| 92 } | 91 } |
| 93 | 92 |
| 94 aura::Window* BaseFocusRules::GetToplevelWindow(aura::Window* window) const { | 93 aura::Window* BaseFocusRules::GetToplevelWindow(aura::Window* window) const { |
| 95 aura::Window* parent = window->parent(); | 94 aura::Window* parent = window->parent(); |
| 96 aura::Window* child = window; | 95 aura::Window* child = window; |
| 97 while (parent) { | 96 while (parent) { |
| 98 if (IsToplevelWindow(child)) | 97 if (IsToplevelWindow(child)) |
| 99 return child; | 98 return child; |
| 100 | 99 |
| 101 parent = parent->parent(); | 100 parent = parent->parent(); |
| 102 child = child->parent(); | 101 child = child->parent(); |
| 103 } | 102 } |
| 104 return NULL; | 103 return nullptr; |
| 105 } | 104 } |
| 106 | 105 |
| 107 aura::Window* BaseFocusRules::GetActivatableWindow(aura::Window* window) const { | 106 aura::Window* BaseFocusRules::GetActivatableWindow(aura::Window* window) const { |
| 108 aura::Window* parent = window->parent(); | 107 aura::Window* parent = window->parent(); |
| 109 aura::Window* child = window; | 108 aura::Window* child = window; |
| 110 while (parent) { | 109 while (parent) { |
| 111 if (CanActivateWindow(child)) | 110 if (CanActivateWindow(child)) |
| 112 return child; | 111 return child; |
| 113 | 112 |
| 114 // CanActivateWindow() above will return false if |child| is blocked by a | 113 // CanActivateWindow() above will return false if |child| is blocked by a |
| (...skipping 11 matching lines...) Expand all Loading... |
| 126 GetModalTransient(wm::GetTransientParent(child)); | 125 GetModalTransient(wm::GetTransientParent(child)); |
| 127 if (parent_modal_transient == child) | 126 if (parent_modal_transient == child) |
| 128 return child; | 127 return child; |
| 129 | 128 |
| 130 return GetActivatableWindow(wm::GetTransientParent(child)); | 129 return GetActivatableWindow(wm::GetTransientParent(child)); |
| 131 } | 130 } |
| 132 | 131 |
| 133 parent = parent->parent(); | 132 parent = parent->parent(); |
| 134 child = child->parent(); | 133 child = child->parent(); |
| 135 } | 134 } |
| 136 return NULL; | 135 return nullptr; |
| 137 } | 136 } |
| 138 | 137 |
| 139 aura::Window* BaseFocusRules::GetFocusableWindow(aura::Window* window) const { | 138 aura::Window* BaseFocusRules::GetFocusableWindow(aura::Window* window) const { |
| 140 if (CanFocusWindow(window)) | 139 if (CanFocusWindow(window, nullptr)) |
| 141 return window; | 140 return window; |
| 142 | 141 |
| 143 // |window| may be in a hierarchy that is non-activatable, in which case we | 142 // |window| may be in a hierarchy that is non-activatable, in which case we |
| 144 // need to cut over to the activatable hierarchy. | 143 // need to cut over to the activatable hierarchy. |
| 145 aura::Window* activatable = GetActivatableWindow(window); | 144 aura::Window* activatable = GetActivatableWindow(window); |
| 146 if (!activatable) { | 145 if (!activatable) { |
| 147 // There may not be a related activatable hierarchy to cut over to, in which | 146 // There may not be a related activatable hierarchy to cut over to, in which |
| 148 // case we try an unrelated one. | 147 // case we try an unrelated one. |
| 149 aura::Window* toplevel = GetToplevelWindow(window); | 148 aura::Window* toplevel = GetToplevelWindow(window); |
| 150 if (toplevel) | 149 if (toplevel) |
| 151 activatable = GetNextActivatableWindow(toplevel); | 150 activatable = GetNextActivatableWindow(toplevel); |
| 152 if (!activatable) | 151 if (!activatable) |
| 153 return NULL; | 152 return nullptr; |
| 154 } | 153 } |
| 155 | 154 |
| 156 if (!activatable->Contains(window)) { | 155 if (!activatable->Contains(window)) { |
| 157 // If there's already a child window focused in the activatable hierarchy, | 156 // If there's already a child window focused in the activatable hierarchy, |
| 158 // just use that (i.e. don't shift focus), otherwise we need to at least cut | 157 // just use that (i.e. don't shift focus), otherwise we need to at least cut |
| 159 // over to the activatable hierarchy. | 158 // over to the activatable hierarchy. |
| 160 aura::Window* focused = GetFocusedWindow(activatable); | 159 aura::Window* focused = GetFocusedWindow(activatable); |
| 161 return activatable->Contains(focused) ? focused : activatable; | 160 return activatable->Contains(focused) ? focused : activatable; |
| 162 } | 161 } |
| 163 | 162 |
| 164 while (window && !CanFocusWindow(window)) | 163 while (window && !CanFocusWindow(window, nullptr)) |
| 165 window = window->parent(); | 164 window = window->parent(); |
| 166 return window; | 165 return window; |
| 167 } | 166 } |
| 168 | 167 |
| 169 aura::Window* BaseFocusRules::GetNextActivatableWindow( | 168 aura::Window* BaseFocusRules::GetNextActivatableWindow( |
| 170 aura::Window* ignore) const { | 169 aura::Window* ignore) const { |
| 171 DCHECK(ignore); | 170 DCHECK(ignore); |
| 172 | 171 |
| 173 // Can be called from the RootWindow's destruction, which has a NULL parent. | 172 // Can be called from the RootWindow's destruction, which has a NULL parent. |
| 174 if (!ignore->parent()) | 173 if (!ignore->parent()) |
| 175 return NULL; | 174 return nullptr; |
| 176 | 175 |
| 177 // In the basic scenarios handled by BasicFocusRules, the pool of activatable | 176 // In the basic scenarios handled by BasicFocusRules, the pool of activatable |
| 178 // windows is limited to the |ignore|'s siblings. | 177 // windows is limited to the |ignore|'s siblings. |
| 179 const aura::Window::Windows& siblings = ignore->parent()->children(); | 178 const aura::Window::Windows& siblings = ignore->parent()->children(); |
| 180 DCHECK(!siblings.empty()); | 179 DCHECK(!siblings.empty()); |
| 181 | 180 |
| 182 for (aura::Window::Windows::const_reverse_iterator rit = siblings.rbegin(); | 181 for (aura::Window::Windows::const_reverse_iterator rit = siblings.rbegin(); |
| 183 rit != siblings.rend(); | 182 rit != siblings.rend(); |
| 184 ++rit) { | 183 ++rit) { |
| 185 aura::Window* cur = *rit; | 184 aura::Window* cur = *rit; |
| 186 if (cur == ignore) | 185 if (cur == ignore) |
| 187 continue; | 186 continue; |
| 188 if (CanActivateWindow(cur)) | 187 if (CanActivateWindow(cur)) |
| 189 return cur; | 188 return cur; |
| 190 } | 189 } |
| 191 return NULL; | 190 return nullptr; |
| 192 } | 191 } |
| 193 | 192 |
| 194 } // namespace wm | 193 } // namespace wm |
| OLD | NEW |