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. |
210 aura::Window* last_focused_window = focused_window_; | 211 aura::Window* last_focused_window = focused_window_; |
211 if (!updating_activation_) | 212 if (!updating_activation_) |
212 SetActiveWindow(reason, window, activatable); | 213 SetActiveWindow(reason, window, activatable); |
213 | 214 |
214 // If the window's ActivationChangeObserver shifted focus to a valid window, | 215 // If the window's ActivationChangeObserver shifted focus to a valid window, |
215 // we don't want to focus the window we thought would be focused by default. | 216 // we don't want to focus the window we thought would be focused by default. |
216 bool activation_changed_focus = last_focused_window != focused_window_; | 217 bool activation_changed_focus = last_focused_window != focused_window_; |
217 if (!updating_focus_ && (!activation_changed_focus || !focused_window_)) { | 218 if (!updating_focus_ && (!activation_changed_focus || !focused_window_)) { |
218 if (active_window_ && focusable) | 219 if (active_window_ && focusable) |
219 DCHECK(active_window_->Contains(focusable)); | 220 DCHECK(active_window_->Contains(focusable)); |
220 SetFocusedWindow(focusable); | 221 SetFocusedWindow(focusable); |
221 } | 222 } |
222 } | 223 } |
223 | 224 |
224 void FocusController::SetFocusedWindow(aura::Window* window) { | 225 void FocusController::SetFocusedWindow(aura::Window* window) { |
225 if (updating_focus_ || window == focused_window_) | 226 if (updating_focus_ || window == focused_window_) |
226 return; | 227 return; |
227 DCHECK(rules_->CanFocusWindow(window)); | 228 DCHECK(rules_->CanFocusWindow(window, nullptr)); |
228 if (window) | 229 if (window) |
229 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); | 230 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); |
230 | 231 |
231 base::AutoReset<bool> updating_focus(&updating_focus_, true); | 232 base::AutoReset<bool> updating_focus(&updating_focus_, true); |
232 aura::Window* lost_focus = focused_window_; | 233 aura::Window* lost_focus = focused_window_; |
233 | 234 |
234 // Allow for the window losing focus to be deleted during dispatch. If it is | 235 // Allow for the window losing focus to be deleted during dispatch. If it is |
235 // deleted pass NULL to observers instead of a deleted window. | 236 // deleted pass NULL to observers instead of a deleted window. |
236 aura::WindowTracker window_tracker; | 237 aura::WindowTracker window_tracker; |
237 if (lost_focus) | 238 if (lost_focus) |
238 window_tracker.Add(lost_focus); | 239 window_tracker.Add(lost_focus); |
239 if (focused_window_ && observer_manager_.IsObserving(focused_window_) && | 240 if (focused_window_ && observer_manager_.IsObserving(focused_window_) && |
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) { |
351 // Only focus |window| if it or any of its parents can be focused. Otherwise | 353 // 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 | 354 // FocusWindow() will focus the topmost window, which may not be the |
353 // currently focused one. | 355 // currently focused one. |
354 if (rules_->CanFocusWindow(GetToplevelWindow(window))) { | 356 if (rules_->CanFocusWindow(GetToplevelWindow(window), event)) { |
355 FocusAndActivateWindow( | 357 FocusAndActivateWindow( |
356 aura::client::ActivationChangeObserver::ActivationReason::INPUT_EVENT, | 358 aura::client::ActivationChangeObserver::ActivationReason::INPUT_EVENT, |
357 window); | 359 window); |
358 } | 360 } |
359 } | 361 } |
360 | 362 |
361 } // namespace wm | 363 } // namespace wm |
OLD | NEW |