| 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/focus_controller.h" | 5 #include "ui/wm/core/focus_controller.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "ui/aura/client/aura_constants.h" | 8 #include "ui/aura/client/aura_constants.h" |
| 9 #include "ui/aura/client/capture_client.h" | 9 #include "ui/aura/client/capture_client.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 transient_parent = wm::GetTransientParent(transient_parent); | 31 transient_parent = wm::GetTransientParent(transient_parent); |
| 32 } | 32 } |
| 33 } | 33 } |
| 34 | 34 |
| 35 } // namespace | 35 } // namespace |
| 36 | 36 |
| 37 //////////////////////////////////////////////////////////////////////////////// | 37 //////////////////////////////////////////////////////////////////////////////// |
| 38 // FocusController, public: | 38 // FocusController, public: |
| 39 | 39 |
| 40 FocusController::FocusController(FocusRules* rules) | 40 FocusController::FocusController(FocusRules* rules) |
| 41 : active_window_(NULL), | 41 : active_window_(nullptr), |
| 42 focused_window_(NULL), | 42 focused_window_(nullptr), |
| 43 updating_focus_(false), | 43 updating_focus_(false), |
| 44 updating_activation_(false), | 44 updating_activation_(false), |
| 45 rules_(rules), | 45 rules_(rules), |
| 46 observer_manager_(this) { | 46 observer_manager_(this) { |
| 47 DCHECK(rules); | 47 DCHECK(rules); |
| 48 } | 48 } |
| 49 | 49 |
| 50 FocusController::~FocusController() { | 50 FocusController::~FocusController() = default; |
| 51 } | |
| 52 | 51 |
| 53 //////////////////////////////////////////////////////////////////////////////// | 52 //////////////////////////////////////////////////////////////////////////////// |
| 54 // FocusController, aura::client::ActivationClient implementation: | 53 // FocusController, aura::client::ActivationClient implementation: |
| 55 | 54 |
| 56 void FocusController::AddObserver( | 55 void FocusController::AddObserver( |
| 57 aura::client::ActivationChangeObserver* observer) { | 56 aura::client::ActivationChangeObserver* observer) { |
| 58 activation_observers_.AddObserver(observer); | 57 activation_observers_.AddObserver(observer); |
| 59 } | 58 } |
| 60 | 59 |
| 61 void FocusController::RemoveObserver( | 60 void FocusController::RemoveObserver( |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 return focused_window_; | 119 return focused_window_; |
| 121 } | 120 } |
| 122 | 121 |
| 123 //////////////////////////////////////////////////////////////////////////////// | 122 //////////////////////////////////////////////////////////////////////////////// |
| 124 // FocusController, ui::EventHandler implementation: | 123 // FocusController, ui::EventHandler implementation: |
| 125 void FocusController::OnKeyEvent(ui::KeyEvent* event) { | 124 void FocusController::OnKeyEvent(ui::KeyEvent* event) { |
| 126 } | 125 } |
| 127 | 126 |
| 128 void FocusController::OnMouseEvent(ui::MouseEvent* event) { | 127 void FocusController::OnMouseEvent(ui::MouseEvent* event) { |
| 129 if (event->type() == ui::ET_MOUSE_PRESSED && !event->handled()) | 128 if (event->type() == ui::ET_MOUSE_PRESSED && !event->handled()) |
| 130 WindowFocusedFromInputEvent(static_cast<aura::Window*>(event->target())); | 129 WindowFocusedFromInputEvent(static_cast<aura::Window*>(event->target()), |
| 130 event); |
| 131 } | 131 } |
| 132 | 132 |
| 133 void FocusController::OnScrollEvent(ui::ScrollEvent* event) { | 133 void FocusController::OnScrollEvent(ui::ScrollEvent* event) { |
| 134 } | 134 } |
| 135 | 135 |
| 136 void FocusController::OnTouchEvent(ui::TouchEvent* event) { | 136 void FocusController::OnTouchEvent(ui::TouchEvent* event) { |
| 137 } | 137 } |
| 138 | 138 |
| 139 void FocusController::OnGestureEvent(ui::GestureEvent* event) { | 139 void FocusController::OnGestureEvent(ui::GestureEvent* event) { |
| 140 if (event->type() == ui::ET_GESTURE_BEGIN && | 140 if (event->type() == ui::ET_GESTURE_BEGIN && |
| 141 event->details().touch_points() == 1 && | 141 event->details().touch_points() == 1 && |
| 142 !event->handled()) { | 142 !event->handled()) { |
| 143 WindowFocusedFromInputEvent(static_cast<aura::Window*>(event->target())); | 143 WindowFocusedFromInputEvent(static_cast<aura::Window*>(event->target()), |
| 144 event); |
| 144 } | 145 } |
| 145 } | 146 } |
| 146 | 147 |
| 147 //////////////////////////////////////////////////////////////////////////////// | 148 //////////////////////////////////////////////////////////////////////////////// |
| 148 // FocusController, aura::WindowObserver implementation: | 149 // FocusController, aura::WindowObserver implementation: |
| 149 | 150 |
| 150 void FocusController::OnWindowVisibilityChanged(aura::Window* window, | 151 void FocusController::OnWindowVisibilityChanged(aura::Window* window, |
| 151 bool visible) { | 152 bool visible) { |
| 152 if (!visible) | 153 if (!visible) |
| 153 WindowLostFocusFromDispositionChange(window, window->parent()); | 154 WindowLostFocusFromDispositionChange(window, window->parent()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 if (window && | 190 if (window && |
| 190 (window->Contains(focused_window_) || window->Contains(active_window_))) { | 191 (window->Contains(focused_window_) || window->Contains(active_window_))) { |
| 191 StackActiveWindow(); | 192 StackActiveWindow(); |
| 192 return; | 193 return; |
| 193 } | 194 } |
| 194 | 195 |
| 195 // Focusing a window also activates its containing activatable window. Note | 196 // Focusing a window also activates its containing activatable window. Note |
| 196 // that the rules could redirect activation activation and/or focus. | 197 // that the rules could redirect activation activation and/or focus. |
| 197 aura::Window* focusable = rules_->GetFocusableWindow(window); | 198 aura::Window* focusable = rules_->GetFocusableWindow(window); |
| 198 aura::Window* activatable = | 199 aura::Window* activatable = |
| 199 focusable ? rules_->GetActivatableWindow(focusable) : NULL; | 200 focusable ? rules_->GetActivatableWindow(focusable) : nullptr; |
| 200 | 201 |
| 201 // We need valid focusable/activatable windows in the event we're not clearing | 202 // We need valid focusable/activatable windows in the event we're not clearing |
| 202 // focus. "Clearing focus" is inferred by whether or not |window| passed to | 203 // focus. "Clearing focus" is inferred by whether or not |window| passed to |
| 203 // this function is non-NULL. | 204 // this function is non-NULL. |
| 204 if (window && (!focusable || !activatable)) | 205 if (window && (!focusable || !activatable)) |
| 205 return; | 206 return; |
| 206 DCHECK((focusable && activatable) || !window); | 207 DCHECK((focusable && activatable) || !window); |
| 207 | 208 |
| 208 // Activation change observers may change the focused window. If this happens | 209 // Activation change observers may change the focused window. If this happens |
| 209 // we must not adjust the focus below since this will clobber that change. | 210 // we must not adjust the focus below since this will clobber that change. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 240 focused_window_ != active_window_) { | 241 focused_window_ != active_window_) { |
| 241 observer_manager_.Remove(focused_window_); | 242 observer_manager_.Remove(focused_window_); |
| 242 } | 243 } |
| 243 focused_window_ = window; | 244 focused_window_ = window; |
| 244 if (focused_window_ && !observer_manager_.IsObserving(focused_window_)) | 245 if (focused_window_ && !observer_manager_.IsObserving(focused_window_)) |
| 245 observer_manager_.Add(focused_window_); | 246 observer_manager_.Add(focused_window_); |
| 246 | 247 |
| 247 for (auto& observer : focus_observers_) { | 248 for (auto& observer : focus_observers_) { |
| 248 observer.OnWindowFocused( | 249 observer.OnWindowFocused( |
| 249 focused_window_, | 250 focused_window_, |
| 250 window_tracker.Contains(lost_focus) ? lost_focus : NULL); | 251 window_tracker.Contains(lost_focus) ? lost_focus : nullptr); |
| 251 } | 252 } |
| 252 if (window_tracker.Contains(lost_focus)) { | 253 if (window_tracker.Contains(lost_focus)) { |
| 253 aura::client::FocusChangeObserver* observer = | 254 aura::client::FocusChangeObserver* observer = |
| 254 aura::client::GetFocusChangeObserver(lost_focus); | 255 aura::client::GetFocusChangeObserver(lost_focus); |
| 255 if (observer) | 256 if (observer) |
| 256 observer->OnWindowFocused(focused_window_, lost_focus); | 257 observer->OnWindowFocused(focused_window_, lost_focus); |
| 257 } | 258 } |
| 258 aura::client::FocusChangeObserver* observer = | 259 aura::client::FocusChangeObserver* observer = |
| 259 aura::client::GetFocusChangeObserver(focused_window_); | 260 aura::client::GetFocusChangeObserver(focused_window_); |
| 260 if (observer) { | 261 if (observer) { |
| 261 observer->OnWindowFocused( | 262 observer->OnWindowFocused( |
| 262 focused_window_, | 263 focused_window_, |
| 263 window_tracker.Contains(lost_focus) ? lost_focus : NULL); | 264 window_tracker.Contains(lost_focus) ? lost_focus : nullptr); |
| 264 } | 265 } |
| 265 } | 266 } |
| 266 | 267 |
| 267 void FocusController::SetActiveWindow( | 268 void FocusController::SetActiveWindow( |
| 268 aura::client::ActivationChangeObserver::ActivationReason reason, | 269 aura::client::ActivationChangeObserver::ActivationReason reason, |
| 269 aura::Window* requested_window, | 270 aura::Window* requested_window, |
| 270 aura::Window* window) { | 271 aura::Window* window) { |
| 271 if (updating_activation_) | 272 if (updating_activation_) |
| 272 return; | 273 return; |
| 273 | 274 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 293 if (active_window_ && observer_manager_.IsObserving(active_window_) && | 294 if (active_window_ && observer_manager_.IsObserving(active_window_) && |
| 294 focused_window_ != active_window_) { | 295 focused_window_ != active_window_) { |
| 295 observer_manager_.Remove(active_window_); | 296 observer_manager_.Remove(active_window_); |
| 296 } | 297 } |
| 297 active_window_ = window; | 298 active_window_ = window; |
| 298 if (active_window_ && !observer_manager_.IsObserving(active_window_)) | 299 if (active_window_ && !observer_manager_.IsObserving(active_window_)) |
| 299 observer_manager_.Add(active_window_); | 300 observer_manager_.Add(active_window_); |
| 300 if (active_window_) | 301 if (active_window_) |
| 301 StackActiveWindow(); | 302 StackActiveWindow(); |
| 302 | 303 |
| 303 aura::client::ActivationChangeObserver* observer = NULL; | 304 aura::client::ActivationChangeObserver* observer = nullptr; |
| 304 if (window_tracker.Contains(lost_activation)) { | 305 if (window_tracker.Contains(lost_activation)) { |
| 305 observer = aura::client::GetActivationChangeObserver(lost_activation); | 306 observer = aura::client::GetActivationChangeObserver(lost_activation); |
| 306 if (observer) | 307 if (observer) |
| 307 observer->OnWindowActivated(reason, active_window_, lost_activation); | 308 observer->OnWindowActivated(reason, active_window_, lost_activation); |
| 308 } | 309 } |
| 309 observer = aura::client::GetActivationChangeObserver(active_window_); | 310 observer = aura::client::GetActivationChangeObserver(active_window_); |
| 310 if (observer) { | 311 if (observer) { |
| 311 observer->OnWindowActivated( | 312 observer->OnWindowActivated( |
| 312 reason, active_window_, | 313 reason, active_window_, |
| 313 window_tracker.Contains(lost_activation) ? lost_activation : NULL); | 314 window_tracker.Contains(lost_activation) ? lost_activation : nullptr); |
| 314 } | 315 } |
| 315 for (auto& observer : activation_observers_) { | 316 for (auto& observer : activation_observers_) { |
| 316 observer.OnWindowActivated( | 317 observer.OnWindowActivated( |
| 317 reason, active_window_, | 318 reason, active_window_, |
| 318 window_tracker.Contains(lost_activation) ? lost_activation : NULL); | 319 window_tracker.Contains(lost_activation) ? lost_activation : nullptr); |
| 319 } | 320 } |
| 320 } | 321 } |
| 321 | 322 |
| 322 void FocusController::StackActiveWindow() { | 323 void FocusController::StackActiveWindow() { |
| 323 if (active_window_) { | 324 if (active_window_) { |
| 324 StackTransientParentsBelowModalWindow(active_window_); | 325 StackTransientParentsBelowModalWindow(active_window_); |
| 325 active_window_->parent()->StackChildAtTop(active_window_); | 326 active_window_->parent()->StackChildAtTop(active_window_); |
| 326 } | 327 } |
| 327 } | 328 } |
| 328 | 329 |
| 329 void FocusController::WindowLostFocusFromDispositionChange( | 330 void FocusController::WindowLostFocusFromDispositionChange( |
| 330 aura::Window* window, | 331 aura::Window* window, |
| 331 aura::Window* next) { | 332 aura::Window* next) { |
| 332 // TODO(beng): See if this function can be replaced by a call to | 333 // TODO(beng): See if this function can be replaced by a call to |
| 333 // FocusWindow(). | 334 // FocusWindow(). |
| 334 // Activation adjustments are handled first in the event of a disposition | 335 // Activation adjustments are handled first in the event of a disposition |
| 335 // changed. If an activation change is necessary, focus is reset as part of | 336 // changed. If an activation change is necessary, focus is reset as part of |
| 336 // that process so there's no point in updating focus independently. | 337 // that process so there's no point in updating focus independently. |
| 337 if (window == active_window_) { | 338 if (window == active_window_) { |
| 338 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); | 339 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); |
| 339 SetActiveWindow(aura::client::ActivationChangeObserver::ActivationReason:: | 340 SetActiveWindow(aura::client::ActivationChangeObserver::ActivationReason:: |
| 340 WINDOW_DISPOSITION_CHANGED, | 341 WINDOW_DISPOSITION_CHANGED, |
| 341 NULL, next_activatable); | 342 nullptr, next_activatable); |
| 342 if (!(active_window_ && active_window_->Contains(focused_window_))) | 343 if (!(active_window_ && active_window_->Contains(focused_window_))) |
| 343 SetFocusedWindow(next_activatable); | 344 SetFocusedWindow(next_activatable); |
| 344 } else if (window->Contains(focused_window_)) { | 345 } else if (window->Contains(focused_window_)) { |
| 345 // Active window isn't changing, but focused window might be. | 346 // Active window isn't changing, but focused window might be. |
| 346 SetFocusedWindow(rules_->GetFocusableWindow(next)); | 347 SetFocusedWindow(rules_->GetFocusableWindow(next)); |
| 347 } | 348 } |
| 348 } | 349 } |
| 349 | 350 |
| 350 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { | 351 void FocusController::WindowFocusedFromInputEvent(aura::Window* window, |
| 352 ui::Event* event) { |
| 353 if (!rules_->IsWindowConsideredActivatableForEvent(window, event)) |
| 354 return; |
| 355 |
| 351 // Only focus |window| if it or any of its parents can be focused. Otherwise | 356 // Only focus |window| if it or any of its parents can be focused. Otherwise |
| 352 // FocusWindow() will focus the topmost window, which may not be the | 357 // FocusWindow() will focus the topmost window, which may not be the |
| 353 // currently focused one. | 358 // currently focused one. |
| 354 if (rules_->CanFocusWindow(GetToplevelWindow(window))) { | 359 if (rules_->CanFocusWindow(GetToplevelWindow(window))) { |
| 355 FocusAndActivateWindow( | 360 FocusAndActivateWindow( |
| 356 aura::client::ActivationChangeObserver::ActivationReason::INPUT_EVENT, | 361 aura::client::ActivationChangeObserver::ActivationReason::INPUT_EVENT, |
| 357 window); | 362 window); |
| 358 } | 363 } |
| 359 } | 364 } |
| 360 | 365 |
| 361 } // namespace wm | 366 } // namespace wm |
| OLD | NEW |