| 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/focus_controller.h" | 5 #include "ui/views/corewm/focus_controller.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "ui/aura/client/activation_change_observer.h" | 8 #include "ui/aura/client/activation_change_observer.h" |
| 9 #include "ui/aura/client/aura_constants.h" | 9 #include "ui/aura/client/aura_constants.h" |
| 10 #include "ui/aura/client/focus_change_observer.h" | 10 #include "ui/aura/client/focus_change_observer.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 } | 31 } |
| 32 | 32 |
| 33 } // namespace | 33 } // namespace |
| 34 | 34 |
| 35 //////////////////////////////////////////////////////////////////////////////// | 35 //////////////////////////////////////////////////////////////////////////////// |
| 36 // FocusController, public: | 36 // FocusController, public: |
| 37 | 37 |
| 38 FocusController::FocusController(FocusRules* rules) | 38 FocusController::FocusController(FocusRules* rules) |
| 39 : active_window_(NULL), | 39 : active_window_(NULL), |
| 40 focused_window_(NULL), | 40 focused_window_(NULL), |
| 41 updating_focus_(false), |
| 41 rules_(rules), | 42 rules_(rules), |
| 42 ALLOW_THIS_IN_INITIALIZER_LIST(observer_manager_(this)) { | 43 ALLOW_THIS_IN_INITIALIZER_LIST(observer_manager_(this)) { |
| 43 DCHECK(rules); | 44 DCHECK(rules); |
| 44 aura::Env::GetInstance()->AddObserver(this); | 45 aura::Env::GetInstance()->AddObserver(this); |
| 45 } | 46 } |
| 46 | 47 |
| 47 FocusController::~FocusController() { | 48 FocusController::~FocusController() { |
| 48 aura::Env::GetInstance()->RemoveObserver(this); | 49 aura::Env::GetInstance()->RemoveObserver(this); |
| 49 } | 50 } |
| 50 | 51 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 focus_observers_.AddObserver(observer); | 101 focus_observers_.AddObserver(observer); |
| 101 } | 102 } |
| 102 | 103 |
| 103 void FocusController::RemoveObserver( | 104 void FocusController::RemoveObserver( |
| 104 aura::client::FocusChangeObserver* observer) { | 105 aura::client::FocusChangeObserver* observer) { |
| 105 focus_observers_.RemoveObserver(observer); | 106 focus_observers_.RemoveObserver(observer); |
| 106 } | 107 } |
| 107 | 108 |
| 108 void FocusController::FocusWindow(aura::Window* window, | 109 void FocusController::FocusWindow(aura::Window* window, |
| 109 const ui::Event* event) { | 110 const ui::Event* event) { |
| 111 if (updating_focus_) |
| 112 return; |
| 113 |
| 114 if (window && |
| 115 (window->Contains(focused_window_) || window->Contains(active_window_))) { |
| 116 return; |
| 117 } |
| 118 |
| 110 // Focusing a window also activates its containing activatable window. Note | 119 // Focusing a window also activates its containing activatable window. Note |
| 111 // that the rules could redirect activation activation and/or focus. | 120 // that the rules could redirect activation activation and/or focus. |
| 112 aura::Window* focusable = rules_->GetFocusableWindow(window); | 121 aura::Window* focusable = rules_->GetFocusableWindow(window); |
| 113 aura::Window* activatable = | 122 aura::Window* activatable = |
| 114 focusable ? rules_->GetActivatableWindow(focusable) : NULL; | 123 focusable ? rules_->GetActivatableWindow(focusable) : NULL; |
| 124 |
| 125 // We need valid focusable/activatable windows in the event we're not clearing |
| 126 // focus. "Clearing focus" is inferred by whether or not |window| passed to |
| 127 // this function is non-NULL. |
| 128 if (window && (!focusable || !activatable)) |
| 129 return; |
| 130 DCHECK((focusable && activatable) || !window); |
| 115 SetActiveWindow(activatable); | 131 SetActiveWindow(activatable); |
| 116 if (focusable && activatable) | 132 if (active_window_) |
| 117 DCHECK(GetActiveWindow()->Contains(focusable)); | 133 DCHECK(active_window_->Contains(focusable)); |
| 118 SetFocusedWindow(focusable); | 134 SetFocusedWindow(focusable); |
| 119 } | 135 } |
| 120 | 136 |
| 121 aura::Window* FocusController::GetFocusedWindow() { | 137 aura::Window* FocusController::GetFocusedWindow() { |
| 122 return focused_window_; | 138 return focused_window_; |
| 123 } | 139 } |
| 124 | 140 |
| 125 void FocusController::OnWindowHiddenInRootWindow( | 141 void FocusController::OnWindowHiddenInRootWindow( |
| 126 aura::Window* window, | 142 aura::Window* window, |
| 127 aura::RootWindow* root_window, | 143 aura::RootWindow* root_window, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } | 204 } |
| 189 | 205 |
| 190 void FocusController::OnWindowInitialized(aura::Window* window) { | 206 void FocusController::OnWindowInitialized(aura::Window* window) { |
| 191 observer_manager_.Add(window); | 207 observer_manager_.Add(window); |
| 192 } | 208 } |
| 193 | 209 |
| 194 //////////////////////////////////////////////////////////////////////////////// | 210 //////////////////////////////////////////////////////////////////////////////// |
| 195 // FocusController, private: | 211 // FocusController, private: |
| 196 | 212 |
| 197 void FocusController::SetFocusedWindow(aura::Window* window) { | 213 void FocusController::SetFocusedWindow(aura::Window* window) { |
| 198 if (window == focused_window_) | 214 if (updating_focus_ || window == focused_window_) |
| 199 return; | 215 return; |
| 200 DCHECK(rules_->CanFocusWindow(window)); | 216 DCHECK(rules_->CanFocusWindow(window)); |
| 201 if (window) | 217 if (window) |
| 202 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); | 218 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); |
| 203 | 219 |
| 220 base::AutoReset<bool> updating_focus(&updating_focus_, true); |
| 204 aura::Window* lost_focus = focused_window_; | 221 aura::Window* lost_focus = focused_window_; |
| 205 focused_window_ = window; | 222 focused_window_ = window; |
| 206 | 223 |
| 207 FOR_EACH_OBSERVER(aura::client::FocusChangeObserver, | 224 FOR_EACH_OBSERVER(aura::client::FocusChangeObserver, |
| 208 focus_observers_, | 225 focus_observers_, |
| 209 OnWindowFocused(focused_window_, lost_focus)); | 226 OnWindowFocused(focused_window_, lost_focus)); |
| 210 aura::client::FocusChangeObserver* observer = | 227 aura::client::FocusChangeObserver* observer = |
| 211 aura::client::GetFocusChangeObserver(lost_focus); | 228 aura::client::GetFocusChangeObserver(lost_focus); |
| 212 if (observer) | 229 if (observer) |
| 213 observer->OnWindowFocused(focused_window_, lost_focus); | 230 observer->OnWindowFocused(focused_window_, lost_focus); |
| 214 observer = aura::client::GetFocusChangeObserver(focused_window_); | 231 observer = aura::client::GetFocusChangeObserver(focused_window_); |
| 215 if (observer) | 232 if (observer) |
| 216 observer->OnWindowFocused(focused_window_, lost_focus); | 233 observer->OnWindowFocused(focused_window_, lost_focus); |
| 217 } | 234 } |
| 218 | 235 |
| 219 void FocusController::SetActiveWindow(aura::Window* window) { | 236 void FocusController::SetActiveWindow(aura::Window* window) { |
| 220 if (window == active_window_) | 237 if (updating_focus_ || window == active_window_) |
| 221 return; | 238 return; |
| 239 |
| 222 DCHECK(rules_->CanActivateWindow(window)); | 240 DCHECK(rules_->CanActivateWindow(window)); |
| 223 if (window) | 241 if (window) |
| 224 DCHECK_EQ(window, rules_->GetActivatableWindow(window)); | 242 DCHECK_EQ(window, rules_->GetActivatableWindow(window)); |
| 225 | 243 |
| 244 base::AutoReset<bool> updating_focus(&updating_focus_, true); |
| 226 aura::Window* lost_activation = active_window_; | 245 aura::Window* lost_activation = active_window_; |
| 227 active_window_ = window; | 246 active_window_ = window; |
| 228 if (active_window_) { | 247 if (active_window_) { |
| 229 StackTransientParentsBelowModalWindow(active_window_); | 248 StackTransientParentsBelowModalWindow(active_window_); |
| 230 active_window_->parent()->StackChildAtTop(active_window_); | 249 active_window_->parent()->StackChildAtTop(active_window_); |
| 231 } | 250 } |
| 232 | 251 |
| 233 FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, | 252 FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, |
| 234 activation_observers_, | 253 activation_observers_, |
| 235 OnWindowActivated(active_window_, lost_activation)); | 254 OnWindowActivated(active_window_, lost_activation)); |
| 236 aura::client::ActivationChangeObserver* observer = | 255 aura::client::ActivationChangeObserver* observer = |
| 237 aura::client::GetActivationChangeObserver(lost_activation); | 256 aura::client::GetActivationChangeObserver(lost_activation); |
| 238 if (observer) | 257 if (observer) |
| 239 observer->OnWindowActivated(active_window_, lost_activation); | 258 observer->OnWindowActivated(active_window_, lost_activation); |
| 240 observer = aura::client::GetActivationChangeObserver(active_window_); | 259 observer = aura::client::GetActivationChangeObserver(active_window_); |
| 241 if (observer) | 260 if (observer) |
| 242 observer->OnWindowActivated(active_window_, lost_activation); | 261 observer->OnWindowActivated(active_window_, lost_activation); |
| 243 } | 262 } |
| 244 | 263 |
| 245 void FocusController::WindowLostFocusFromDispositionChange( | 264 void FocusController::WindowLostFocusFromDispositionChange( |
| 246 aura::Window* window) { | 265 aura::Window* window) { |
| 266 // A window's modality state will interfere with focus restoration during its |
| 267 // destruction. |
| 268 window->ClearProperty(aura::client::kModalKey); |
| 247 // TODO(beng): See if this function can be replaced by a call to | 269 // TODO(beng): See if this function can be replaced by a call to |
| 248 // FocusWindow(). | 270 // FocusWindow(). |
| 249 // Activation adjustments are handled first in the event of a disposition | 271 // Activation adjustments are handled first in the event of a disposition |
| 250 // changed. If an activation change is necessary, focus is reset as part of | 272 // changed. If an activation change is necessary, focus is reset as part of |
| 251 // that process so there's no point in updating focus independently. | 273 // that process so there's no point in updating focus independently. |
| 252 if (window->Contains(active_window_)) { | 274 if (window == active_window_) { |
| 253 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); | 275 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); |
| 254 SetActiveWindow(next_activatable); | 276 SetActiveWindow(next_activatable); |
| 255 SetFocusedWindow(next_activatable); | 277 SetFocusedWindow(next_activatable); |
| 256 } else if (window->Contains(focused_window_)) { | 278 } else if (window->Contains(focused_window_)) { |
| 257 // Active window isn't changing, but focused window might be. | 279 // Active window isn't changing, but focused window might be. |
| 258 SetFocusedWindow(rules_->GetNextFocusableWindow(window)); | 280 SetFocusedWindow(rules_->GetNextFocusableWindow(window)); |
| 259 } | 281 } |
| 260 } | 282 } |
| 261 | 283 |
| 262 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { | 284 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { |
| 263 FocusWindow(window, NULL); | 285 FocusWindow(window, NULL); |
| 264 } | 286 } |
| 265 | 287 |
| 266 } // namespace corewm | 288 } // namespace corewm |
| 267 } // namespace views | 289 } // namespace views |
| OLD | NEW |