Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: ui/wm/core/focus_controller.cc

Issue 1151133003: Added an ActivationReason parameter to ActivationChangeObserver::OnWindowActivated(...). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Uploaded diff based on dependant CL. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/wm/core/focus_controller.h ('k') | ui/wm/core/focus_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 aura::client::FocusChangeObserver* observer) { 96 aura::client::FocusChangeObserver* observer) {
97 focus_observers_.AddObserver(observer); 97 focus_observers_.AddObserver(observer);
98 } 98 }
99 99
100 void FocusController::RemoveObserver( 100 void FocusController::RemoveObserver(
101 aura::client::FocusChangeObserver* observer) { 101 aura::client::FocusChangeObserver* observer) {
102 focus_observers_.RemoveObserver(observer); 102 focus_observers_.RemoveObserver(observer);
103 } 103 }
104 104
105 void FocusController::FocusWindow(aura::Window* window) { 105 void FocusController::FocusWindow(aura::Window* window) {
106 if (window && 106 FocusAndActivateWindow(aura::client::ActivationChangeObserver::
107 (window->Contains(focused_window_) || window->Contains(active_window_))) { 107 ActivationReason::ACTIVATION_CLIENT,
108 return; 108 window);
109 }
110
111 // Focusing a window also activates its containing activatable window. Note
112 // that the rules could redirect activation activation and/or focus.
113 aura::Window* focusable = rules_->GetFocusableWindow(window);
114 aura::Window* activatable =
115 focusable ? rules_->GetActivatableWindow(focusable) : NULL;
116
117 // We need valid focusable/activatable windows in the event we're not clearing
118 // focus. "Clearing focus" is inferred by whether or not |window| passed to
119 // this function is non-NULL.
120 if (window && (!focusable || !activatable))
121 return;
122 DCHECK((focusable && activatable) || !window);
123
124 // Activation change observers may change the focused window. If this happens
125 // we must not adjust the focus below since this will clobber that change.
126 aura::Window* last_focused_window = focused_window_;
127 if (!updating_activation_)
128 SetActiveWindow(window, activatable);
129
130 // If the window's ActivationChangeObserver shifted focus to a valid window,
131 // we don't want to focus the window we thought would be focused by default.
132 bool activation_changed_focus = last_focused_window != focused_window_;
133 if (!updating_focus_ && (!activation_changed_focus || !focused_window_)) {
134 if (active_window_ && focusable)
135 DCHECK(active_window_->Contains(focusable));
136 SetFocusedWindow(focusable);
137 }
138 } 109 }
139 110
140 void FocusController::ResetFocusWithinActiveWindow(aura::Window* window) { 111 void FocusController::ResetFocusWithinActiveWindow(aura::Window* window) {
141 DCHECK(window); 112 DCHECK(window);
142 if (!active_window_) 113 if (!active_window_)
143 return; 114 return;
144 if (!active_window_->Contains(window)) 115 if (!active_window_->Contains(window))
145 return; 116 return;
146 SetFocusedWindow(window); 117 SetFocusedWindow(window);
147 } 118 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 params.target->Contains(params.receiver) && (!params.new_parent || 177 params.target->Contains(params.receiver) && (!params.new_parent ||
207 aura::client::GetFocusClient(params.new_parent) != 178 aura::client::GetFocusClient(params.new_parent) !=
208 aura::client::GetFocusClient(params.receiver))) { 179 aura::client::GetFocusClient(params.receiver))) {
209 WindowLostFocusFromDispositionChange(params.receiver, params.old_parent); 180 WindowLostFocusFromDispositionChange(params.receiver, params.old_parent);
210 } 181 }
211 } 182 }
212 183
213 //////////////////////////////////////////////////////////////////////////////// 184 ////////////////////////////////////////////////////////////////////////////////
214 // FocusController, private: 185 // FocusController, private:
215 186
187 void FocusController::FocusAndActivateWindow(
188 aura::client::ActivationChangeObserver::ActivationReason reason,
189 aura::Window* window) {
190 if (window &&
191 (window->Contains(focused_window_) || window->Contains(active_window_))) {
192 return;
193 }
194
195 // Focusing a window also activates its containing activatable window. Note
196 // that the rules could redirect activation activation and/or focus.
197 aura::Window* focusable = rules_->GetFocusableWindow(window);
198 aura::Window* activatable =
199 focusable ? rules_->GetActivatableWindow(focusable) : NULL;
200
201 // 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 // this function is non-NULL.
204 if (window && (!focusable || !activatable))
205 return;
206 DCHECK((focusable && activatable) || !window);
207
208 // 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 aura::Window* last_focused_window = focused_window_;
211 if (!updating_activation_)
212 SetActiveWindow(reason, window, activatable);
213
214 // 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 bool activation_changed_focus = last_focused_window != focused_window_;
217 if (!updating_focus_ && (!activation_changed_focus || !focused_window_)) {
218 if (active_window_ && focusable)
219 DCHECK(active_window_->Contains(focusable));
220 SetFocusedWindow(focusable);
221 }
222 }
223
216 void FocusController::SetFocusedWindow(aura::Window* window) { 224 void FocusController::SetFocusedWindow(aura::Window* window) {
217 if (updating_focus_ || window == focused_window_) 225 if (updating_focus_ || window == focused_window_)
218 return; 226 return;
219 DCHECK(rules_->CanFocusWindow(window)); 227 DCHECK(rules_->CanFocusWindow(window));
220 if (window) 228 if (window)
221 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); 229 DCHECK_EQ(window, rules_->GetFocusableWindow(window));
222 230
223 base::AutoReset<bool> updating_focus(&updating_focus_, true); 231 base::AutoReset<bool> updating_focus(&updating_focus_, true);
224 aura::Window* lost_focus = focused_window_; 232 aura::Window* lost_focus = focused_window_;
225 233
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 observer->OnWindowFocused( 269 observer->OnWindowFocused(
262 focused_window_, 270 focused_window_,
263 window_tracker.Contains(lost_focus) ? lost_focus : NULL); 271 window_tracker.Contains(lost_focus) ? lost_focus : NULL);
264 } 272 }
265 273
266 // Ensure that the text input client is reset when the window loses the focus. 274 // Ensure that the text input client is reset when the window loses the focus.
267 if (!window) 275 if (!window)
268 text_input_focus_manager->FocusTextInputClient(NULL); 276 text_input_focus_manager->FocusTextInputClient(NULL);
269 } 277 }
270 278
271 void FocusController::SetActiveWindow(aura::Window* requested_window, 279 void FocusController::SetActiveWindow(
272 aura::Window* window) { 280 aura::client::ActivationChangeObserver::ActivationReason reason,
281 aura::Window* requested_window,
282 aura::Window* window) {
273 if (updating_activation_) 283 if (updating_activation_)
274 return; 284 return;
275 285
276 if (window == active_window_) { 286 if (window == active_window_) {
277 if (requested_window) { 287 if (requested_window) {
278 FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, 288 FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver,
279 activation_observers_, 289 activation_observers_,
280 OnAttemptToReactivateWindow(requested_window, 290 OnAttemptToReactivateWindow(requested_window,
281 active_window_)); 291 active_window_));
282 } 292 }
(...skipping 20 matching lines...) Expand all
303 observer_manager_.Add(active_window_); 313 observer_manager_.Add(active_window_);
304 if (active_window_) { 314 if (active_window_) {
305 StackTransientParentsBelowModalWindow(active_window_); 315 StackTransientParentsBelowModalWindow(active_window_);
306 active_window_->parent()->StackChildAtTop(active_window_); 316 active_window_->parent()->StackChildAtTop(active_window_);
307 } 317 }
308 318
309 aura::client::ActivationChangeObserver* observer = NULL; 319 aura::client::ActivationChangeObserver* observer = NULL;
310 if (window_tracker.Contains(lost_activation)) { 320 if (window_tracker.Contains(lost_activation)) {
311 observer = aura::client::GetActivationChangeObserver(lost_activation); 321 observer = aura::client::GetActivationChangeObserver(lost_activation);
312 if (observer) 322 if (observer)
313 observer->OnWindowActivated(active_window_, lost_activation); 323 observer->OnWindowActivated(reason, active_window_, lost_activation);
314 } 324 }
315 observer = aura::client::GetActivationChangeObserver(active_window_); 325 observer = aura::client::GetActivationChangeObserver(active_window_);
316 if (observer) { 326 if (observer) {
317 observer->OnWindowActivated( 327 observer->OnWindowActivated(
318 active_window_, 328 reason, active_window_,
319 window_tracker.Contains(lost_activation) ? lost_activation : NULL); 329 window_tracker.Contains(lost_activation) ? lost_activation : NULL);
320 } 330 }
321 FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver, 331 FOR_EACH_OBSERVER(
322 activation_observers_, 332 aura::client::ActivationChangeObserver, activation_observers_,
323 OnWindowActivated(active_window_, 333 OnWindowActivated(
324 window_tracker.Contains(lost_activation) ? 334 reason, active_window_,
325 lost_activation : NULL)); 335 window_tracker.Contains(lost_activation) ? lost_activation : NULL));
326 } 336 }
327 337
328 void FocusController::WindowLostFocusFromDispositionChange( 338 void FocusController::WindowLostFocusFromDispositionChange(
329 aura::Window* window, 339 aura::Window* window,
330 aura::Window* next) { 340 aura::Window* next) {
331 // TODO(beng): See if this function can be replaced by a call to 341 // TODO(beng): See if this function can be replaced by a call to
332 // FocusWindow(). 342 // FocusWindow().
333 // Activation adjustments are handled first in the event of a disposition 343 // Activation adjustments are handled first in the event of a disposition
334 // changed. If an activation change is necessary, focus is reset as part of 344 // changed. If an activation change is necessary, focus is reset as part of
335 // that process so there's no point in updating focus independently. 345 // that process so there's no point in updating focus independently.
336 if (window == active_window_) { 346 if (window == active_window_) {
337 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); 347 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window);
338 SetActiveWindow(NULL, next_activatable); 348 SetActiveWindow(aura::client::ActivationChangeObserver::ActivationReason::
349 WINDOW_DISPOSITION_CHANGED,
350 NULL, next_activatable);
339 if (!(active_window_ && active_window_->Contains(focused_window_))) 351 if (!(active_window_ && active_window_->Contains(focused_window_)))
340 SetFocusedWindow(next_activatable); 352 SetFocusedWindow(next_activatable);
341 } else if (window->Contains(focused_window_)) { 353 } else if (window->Contains(focused_window_)) {
342 // Active window isn't changing, but focused window might be. 354 // Active window isn't changing, but focused window might be.
343 SetFocusedWindow(rules_->GetFocusableWindow(next)); 355 SetFocusedWindow(rules_->GetFocusableWindow(next));
344 } 356 }
345 } 357 }
346 358
347 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { 359 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) {
348 // Only focus |window| if it or any of its parents can be focused. Otherwise 360 // Only focus |window| if it or any of its parents can be focused. Otherwise
349 // FocusWindow() will focus the topmost window, which may not be the 361 // FocusWindow() will focus the topmost window, which may not be the
350 // currently focused one. 362 // currently focused one.
351 if (rules_->CanFocusWindow(GetToplevelWindow(window))) 363 if (rules_->CanFocusWindow(GetToplevelWindow(window))) {
352 FocusWindow(window); 364 FocusAndActivateWindow(
365 aura::client::ActivationChangeObserver::ActivationReason::INPUT_EVENT,
366 window);
367 }
353 } 368 }
354 369
355 } // namespace wm 370 } // namespace wm
OLDNEW
« no previous file with comments | « ui/wm/core/focus_controller.h ('k') | ui/wm/core/focus_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698