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/aura_constants.h" |
8 #include "ui/aura/env.h" | 9 #include "ui/aura/env.h" |
9 #include "ui/views/corewm/focus_change_event.h" | 10 #include "ui/views/corewm/focus_change_event.h" |
10 #include "ui/views/corewm/focus_rules.h" | 11 #include "ui/views/corewm/focus_rules.h" |
11 | 12 |
12 namespace views { | 13 namespace views { |
13 namespace corewm { | 14 namespace corewm { |
14 namespace { | 15 namespace { |
15 | 16 |
| 17 // When a modal window is activated, we bring its entire transient parent chain |
| 18 // to the front. This function must be called before the modal transient is |
| 19 // stacked at the top to ensure correct stacking order. |
| 20 void StackTransientParentsBelowModalWindow(aura::Window* window) { |
| 21 if (window->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_WINDOW) |
| 22 return; |
| 23 |
| 24 aura::Window* transient_parent = window->transient_parent(); |
| 25 while (transient_parent) { |
| 26 transient_parent->parent()->StackChildAtTop(transient_parent); |
| 27 transient_parent = transient_parent->transient_parent(); |
| 28 } |
| 29 } |
| 30 |
16 // Updates focused window state and dispatches changing/changed events. | 31 // Updates focused window state and dispatches changing/changed events. |
17 void DispatchEventsAndUpdateState(ui::EventDispatcher* dispatcher, | 32 void DispatchEventsAndUpdateState(ui::EventDispatcher* dispatcher, |
18 int changing_event_type, | 33 int changing_event_type, |
19 int changed_event_type, | 34 int changed_event_type, |
20 aura::Window** state, | 35 aura::Window** state, |
21 aura::Window* new_state, | 36 aura::Window* new_state, |
| 37 bool restack, |
22 ui::EventTarget** event_dispatch_target) { | 38 ui::EventTarget** event_dispatch_target) { |
23 int result = ui::ER_UNHANDLED; | 39 int result = ui::ER_UNHANDLED; |
24 { | 40 { |
25 base::AutoReset<ui::EventTarget*> reset(event_dispatch_target, *state); | 41 base::AutoReset<ui::EventTarget*> reset(event_dispatch_target, *state); |
26 FocusChangeEvent changing_event(changing_event_type); | 42 FocusChangeEvent changing_event(changing_event_type); |
27 result = dispatcher->ProcessEvent(*state, &changing_event); | 43 result = dispatcher->ProcessEvent(*state, &changing_event); |
28 } | 44 } |
29 DCHECK(!(result & ui::ER_CONSUMED)) | 45 DCHECK(!(result & ui::ER_CONSUMED)) |
30 << "Focus and Activation events cannot be consumed"; | 46 << "Focus and Activation events cannot be consumed"; |
31 | 47 |
32 *state = new_state; | 48 *state = new_state; |
33 | 49 |
| 50 if (restack && new_state) { |
| 51 StackTransientParentsBelowModalWindow(new_state); |
| 52 new_state->parent()->StackChildAtTop(new_state); |
| 53 } |
| 54 |
34 { | 55 { |
35 base::AutoReset<ui::EventTarget*> reset(event_dispatch_target, *state); | 56 base::AutoReset<ui::EventTarget*> reset(event_dispatch_target, *state); |
36 FocusChangeEvent changed_event(changed_event_type); | 57 FocusChangeEvent changed_event(changed_event_type); |
37 dispatcher->ProcessEvent(*state, &changed_event); | 58 dispatcher->ProcessEvent(*state, &changed_event); |
38 } | 59 } |
39 } | 60 } |
40 | 61 |
41 } // namespace | 62 } // namespace |
42 | 63 |
43 //////////////////////////////////////////////////////////////////////////////// | 64 //////////////////////////////////////////////////////////////////////////////// |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 return; | 197 return; |
177 DCHECK(rules_->CanFocusWindow(window)); | 198 DCHECK(rules_->CanFocusWindow(window)); |
178 if (window) | 199 if (window) |
179 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); | 200 DCHECK_EQ(window, rules_->GetFocusableWindow(window)); |
180 DispatchEventsAndUpdateState( | 201 DispatchEventsAndUpdateState( |
181 this, | 202 this, |
182 FocusChangeEvent::focus_changing_event_type(), | 203 FocusChangeEvent::focus_changing_event_type(), |
183 FocusChangeEvent::focus_changed_event_type(), | 204 FocusChangeEvent::focus_changed_event_type(), |
184 &focused_window_, | 205 &focused_window_, |
185 window, | 206 window, |
| 207 /* restack */ false, |
186 &event_dispatch_target_); | 208 &event_dispatch_target_); |
187 } | 209 } |
188 | 210 |
189 void FocusController::SetActiveWindow(aura::Window* window) { | 211 void FocusController::SetActiveWindow(aura::Window* window) { |
190 if (window == active_window_) | 212 if (window == active_window_) |
191 return; | 213 return; |
192 DCHECK(rules_->CanActivateWindow(window)); | 214 DCHECK(rules_->CanActivateWindow(window)); |
193 if (window) | 215 if (window) |
194 DCHECK_EQ(window, rules_->GetActivatableWindow(window)); | 216 DCHECK_EQ(window, rules_->GetActivatableWindow(window)); |
195 DispatchEventsAndUpdateState( | 217 DispatchEventsAndUpdateState( |
196 this, | 218 this, |
197 FocusChangeEvent::activation_changing_event_type(), | 219 FocusChangeEvent::activation_changing_event_type(), |
198 FocusChangeEvent::activation_changed_event_type(), | 220 FocusChangeEvent::activation_changed_event_type(), |
199 &active_window_, | 221 &active_window_, |
200 window, | 222 window, |
| 223 /* restack */ true, |
201 &event_dispatch_target_); | 224 &event_dispatch_target_); |
202 } | 225 } |
203 | 226 |
204 void FocusController::WindowLostFocusFromDispositionChange( | 227 void FocusController::WindowLostFocusFromDispositionChange( |
205 aura::Window* window) { | 228 aura::Window* window) { |
206 // TODO(beng): See if this function can be replaced by a call to | 229 // TODO(beng): See if this function can be replaced by a call to |
207 // FocusWindow(). | 230 // FocusWindow(). |
208 // Activation adjustments are handled first in the event of a disposition | 231 // Activation adjustments are handled first in the event of a disposition |
209 // changed. If an activation change is necessary, focus is reset as part of | 232 // changed. If an activation change is necessary, focus is reset as part of |
210 // that process so there's no point in updating focus independently. | 233 // that process so there's no point in updating focus independently. |
211 if (window->Contains(active_window_)) { | 234 if (window->Contains(active_window_)) { |
212 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); | 235 aura::Window* next_activatable = rules_->GetNextActivatableWindow(window); |
213 SetActiveWindow(next_activatable); | 236 SetActiveWindow(next_activatable); |
214 SetFocusedWindow(next_activatable); | 237 SetFocusedWindow(next_activatable); |
215 } else if (window->Contains(focused_window_)) { | 238 } else if (window->Contains(focused_window_)) { |
216 // Active window isn't changing, but focused window might be. | 239 // Active window isn't changing, but focused window might be. |
217 SetFocusedWindow(rules_->GetNextFocusableWindow(window)); | 240 SetFocusedWindow(rules_->GetNextFocusableWindow(window)); |
218 } | 241 } |
219 } | 242 } |
220 | 243 |
221 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { | 244 void FocusController::WindowFocusedFromInputEvent(aura::Window* window) { |
222 FocusWindow(window); | 245 FocusWindow(window); |
223 } | 246 } |
224 | 247 |
225 } // namespace corewm | 248 } // namespace corewm |
226 } // namespace views | 249 } // namespace views |
OLD | NEW |