OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "services/window_manager/focus_controller.h" | |
6 | |
7 #include "ui/events/event_utils.h" | |
8 #include "mojo/converters/geometry/geometry_type_converters.h" | |
9 #include "services/window_manager/basic_focus_rules.h" | |
10 #include "services/window_manager/capture_controller.h" | |
11 #include "services/window_manager/focus_controller_observer.h" | |
12 #include "services/window_manager/view_event_dispatcher.h" | |
13 #include "services/window_manager/view_targeter.h" | |
14 #include "services/window_manager/window_manager_test_util.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 #include "ui/gfx/geometry/rect.h" | |
17 | |
18 using mojo::View; | |
19 | |
20 namespace window_manager { | |
21 | |
22 // Counts the number of events that occur. | |
23 class FocusNotificationObserver : public FocusControllerObserver { | |
24 public: | |
25 FocusNotificationObserver() | |
26 : activation_changed_count_(0), | |
27 focus_changed_count_(0), | |
28 reactivation_count_(0), | |
29 reactivation_requested_view_(NULL), | |
30 reactivation_actual_view_(NULL) {} | |
31 ~FocusNotificationObserver() override {} | |
32 | |
33 void ExpectCounts(int activation_changed_count, int focus_changed_count) { | |
34 EXPECT_EQ(activation_changed_count, activation_changed_count_); | |
35 EXPECT_EQ(focus_changed_count, focus_changed_count_); | |
36 } | |
37 int reactivation_count() const { return reactivation_count_; } | |
38 View* reactivation_requested_view() const { | |
39 return reactivation_requested_view_; | |
40 } | |
41 View* reactivation_actual_view() const { | |
42 return reactivation_actual_view_; | |
43 } | |
44 | |
45 protected: | |
46 // Overridden from FocusControllerObserver: | |
47 void OnActivated(View* gained_active) override { | |
48 ++activation_changed_count_; | |
49 } | |
50 | |
51 void OnFocused(View* gained_focus) override { ++focus_changed_count_; } | |
52 | |
53 void OnAttemptToReactivateView(View* request_active, | |
54 View* actual_active) override { | |
55 ++reactivation_count_; | |
56 reactivation_requested_view_ = request_active; | |
57 reactivation_actual_view_ = actual_active; | |
58 } | |
59 | |
60 private: | |
61 int activation_changed_count_; | |
62 int focus_changed_count_; | |
63 int reactivation_count_; | |
64 View* reactivation_requested_view_; | |
65 View* reactivation_actual_view_; | |
66 | |
67 DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver); | |
68 }; | |
69 | |
70 class ViewDestroyer { | |
71 public: | |
72 virtual View* GetDestroyedView() = 0; | |
73 | |
74 protected: | |
75 virtual ~ViewDestroyer() {} | |
76 }; | |
77 | |
78 // FocusNotificationObserver that keeps track of whether it was notified about | |
79 // activation changes or focus changes with a destroyed view. | |
80 class RecordingFocusNotificationObserver : public FocusNotificationObserver { | |
81 public: | |
82 RecordingFocusNotificationObserver(FocusController* focus_controller, | |
83 ViewDestroyer* destroyer) | |
84 : focus_controller_(focus_controller), | |
85 destroyer_(destroyer), | |
86 active_(nullptr), | |
87 focus_(nullptr), | |
88 was_notified_with_destroyed_view_(false) { | |
89 focus_controller_->AddObserver(this); | |
90 } | |
91 ~RecordingFocusNotificationObserver() override { | |
92 focus_controller_->RemoveObserver(this); | |
93 } | |
94 | |
95 bool was_notified_with_destroyed_view() const { | |
96 return was_notified_with_destroyed_view_; | |
97 } | |
98 | |
99 // Overridden from FocusNotificationObserver: | |
100 void OnActivated(View* gained_active) override { | |
101 if (active_ && active_ == destroyer_->GetDestroyedView()) | |
102 was_notified_with_destroyed_view_ = true; | |
103 active_ = gained_active; | |
104 } | |
105 | |
106 void OnFocused(View* gained_focus) override { | |
107 if (focus_ && focus_ == destroyer_->GetDestroyedView()) | |
108 was_notified_with_destroyed_view_ = true; | |
109 focus_ = gained_focus; | |
110 } | |
111 | |
112 private: | |
113 FocusController* focus_controller_; | |
114 | |
115 // Not owned. | |
116 ViewDestroyer* destroyer_; | |
117 View* active_; | |
118 View* focus_; | |
119 | |
120 // Whether the observer was notified about the loss of activation or the | |
121 // loss of focus with a view already destroyed by |destroyer_| as the | |
122 // |lost_active| or |lost_focus| parameter. | |
123 bool was_notified_with_destroyed_view_; | |
124 | |
125 DISALLOW_COPY_AND_ASSIGN(RecordingFocusNotificationObserver); | |
126 }; | |
127 | |
128 class DestroyOnLoseActivationFocusNotificationObserver | |
129 : public FocusNotificationObserver, | |
130 public ViewDestroyer { | |
131 public: | |
132 DestroyOnLoseActivationFocusNotificationObserver( | |
133 FocusController* focus_controller, | |
134 View* view_to_destroy, | |
135 View* initial_active) | |
136 : focus_controller_(focus_controller), | |
137 view_to_destroy_(view_to_destroy), | |
138 active_(initial_active), | |
139 did_destroy_(false) { | |
140 focus_controller_->AddObserver(this); | |
141 } | |
142 ~DestroyOnLoseActivationFocusNotificationObserver() override { | |
143 focus_controller_->RemoveObserver(this); | |
144 } | |
145 | |
146 // Overridden from FocusNotificationObserver: | |
147 void OnActivated(View* gained_active) override { | |
148 if (view_to_destroy_ && active_ == view_to_destroy_) { | |
149 view_to_destroy_->Destroy(); | |
150 did_destroy_ = true; | |
151 } | |
152 active_ = gained_active; | |
153 } | |
154 | |
155 // Overridden from ViewDestroyer: | |
156 View* GetDestroyedView() override { | |
157 return did_destroy_ ? view_to_destroy_ : nullptr; | |
158 } | |
159 | |
160 private: | |
161 FocusController* focus_controller_; | |
162 View* view_to_destroy_; | |
163 View* active_; | |
164 bool did_destroy_; | |
165 | |
166 DISALLOW_COPY_AND_ASSIGN(DestroyOnLoseActivationFocusNotificationObserver); | |
167 }; | |
168 | |
169 class ScopedFocusNotificationObserver : public FocusNotificationObserver { | |
170 public: | |
171 ScopedFocusNotificationObserver(FocusController* focus_controller) | |
172 : focus_controller_(focus_controller) { | |
173 focus_controller_->AddObserver(this); | |
174 } | |
175 ~ScopedFocusNotificationObserver() override { | |
176 focus_controller_->RemoveObserver(this); | |
177 } | |
178 | |
179 private: | |
180 FocusController* focus_controller_; | |
181 | |
182 DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver); | |
183 }; | |
184 | |
185 // Only responds to events if a message contains |target| as a parameter. | |
186 class ScopedFilteringFocusNotificationObserver | |
187 : public FocusNotificationObserver { | |
188 public: | |
189 ScopedFilteringFocusNotificationObserver(FocusController* focus_controller, | |
190 View* target, | |
191 View* initial_active, | |
192 View* initial_focus) | |
193 : focus_controller_(focus_controller), | |
194 target_(target), | |
195 active_(initial_active), | |
196 focus_(initial_focus) { | |
197 focus_controller_->AddObserver(this); | |
198 } | |
199 ~ScopedFilteringFocusNotificationObserver() override { | |
200 focus_controller_->RemoveObserver(this); | |
201 } | |
202 | |
203 private: | |
204 // Overridden from FocusControllerObserver: | |
205 void OnActivated(View* gained_active) override { | |
206 if (gained_active == target_ || active_ == target_) | |
207 FocusNotificationObserver::OnActivated(gained_active); | |
208 active_ = gained_active; | |
209 } | |
210 | |
211 void OnFocused(View* gained_focus) override { | |
212 if (gained_focus == target_ || focus_ == target_) | |
213 FocusNotificationObserver::OnFocused(gained_focus); | |
214 focus_ = gained_focus; | |
215 } | |
216 | |
217 void OnAttemptToReactivateView(View* request_active, | |
218 View* actual_active) override { | |
219 if (request_active == target_ || actual_active == target_) { | |
220 FocusNotificationObserver::OnAttemptToReactivateView(request_active, | |
221 actual_active); | |
222 } | |
223 } | |
224 | |
225 FocusController* focus_controller_; | |
226 View* target_; | |
227 View* active_; | |
228 View* focus_; | |
229 | |
230 DISALLOW_COPY_AND_ASSIGN(ScopedFilteringFocusNotificationObserver); | |
231 }; | |
232 | |
233 // Used to fake the handling of events in the pre-target phase. | |
234 class SimpleEventHandler : public ui::EventHandler { | |
235 public: | |
236 SimpleEventHandler() {} | |
237 ~SimpleEventHandler() override {} | |
238 | |
239 // Overridden from ui::EventHandler: | |
240 void OnMouseEvent(ui::MouseEvent* event) override { | |
241 event->SetHandled(); | |
242 } | |
243 void OnGestureEvent(ui::GestureEvent* event) override { | |
244 event->SetHandled(); | |
245 } | |
246 | |
247 private: | |
248 DISALLOW_COPY_AND_ASSIGN(SimpleEventHandler); | |
249 }; | |
250 | |
251 class FocusShiftingActivationObserver | |
252 : public FocusControllerObserver { | |
253 public: | |
254 explicit FocusShiftingActivationObserver(FocusController* focus_controller, | |
255 View* activated_view) | |
256 : focus_controller_(focus_controller), | |
257 activated_view_(activated_view), | |
258 shift_focus_to_(NULL) {} | |
259 ~FocusShiftingActivationObserver() override {} | |
260 | |
261 void set_shift_focus_to(View* shift_focus_to) { | |
262 shift_focus_to_ = shift_focus_to; | |
263 } | |
264 | |
265 private: | |
266 // Overridden from FocusControllerObserver: | |
267 void OnActivated(View* gained_active) override { | |
268 // Shift focus to a child. This should prevent the default focusing from | |
269 // occurring in FocusController::FocusView(). | |
270 if (gained_active == activated_view_) | |
271 focus_controller_->FocusView(shift_focus_to_); | |
272 } | |
273 | |
274 void OnFocused(View* gained_focus) override {} | |
275 | |
276 FocusController* focus_controller_; | |
277 View* activated_view_; | |
278 View* shift_focus_to_; | |
279 | |
280 DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver); | |
281 }; | |
282 | |
283 // BasicFocusRules subclass that allows basic overrides of focus/activation to | |
284 // be tested. This is intended more as a test that the override system works at | |
285 // all, rather than as an exhaustive set of use cases, those should be covered | |
286 // in tests for those FocusRules implementations. | |
287 class TestFocusRules : public BasicFocusRules { | |
288 public: | |
289 TestFocusRules(View* root) | |
290 : BasicFocusRules(root), focus_restriction_(NULL) {} | |
291 | |
292 // Restricts focus and activation to this view and its child hierarchy. | |
293 void set_focus_restriction(View* focus_restriction) { | |
294 focus_restriction_ = focus_restriction; | |
295 } | |
296 | |
297 // Overridden from BasicFocusRules: | |
298 bool SupportsChildActivation(View* view) const override { | |
299 // In FocusControllerTests, only the Root has activatable children. | |
300 return view->GetRoot() == view; | |
301 } | |
302 bool CanActivateView(View* view) const override { | |
303 // Restricting focus to a non-activatable child view means the activatable | |
304 // parent outside the focus restriction is activatable. | |
305 bool can_activate = | |
306 CanFocusOrActivate(view) || view->Contains(focus_restriction_); | |
307 return can_activate ? BasicFocusRules::CanActivateView(view) : false; | |
308 } | |
309 bool CanFocusView(View* view) const override { | |
310 return CanFocusOrActivate(view) ? BasicFocusRules::CanFocusView(view) | |
311 : false; | |
312 } | |
313 View* GetActivatableView(View* view) const override { | |
314 return BasicFocusRules::GetActivatableView( | |
315 CanFocusOrActivate(view) ? view : focus_restriction_); | |
316 } | |
317 View* GetFocusableView(View* view) const override { | |
318 return BasicFocusRules::GetFocusableView( | |
319 CanFocusOrActivate(view) ? view : focus_restriction_); | |
320 } | |
321 View* GetNextActivatableView(View* ignore) const override { | |
322 View* next_activatable = BasicFocusRules::GetNextActivatableView(ignore); | |
323 return CanFocusOrActivate(next_activatable) | |
324 ? next_activatable | |
325 : GetActivatableView(focus_restriction_); | |
326 } | |
327 | |
328 private: | |
329 bool CanFocusOrActivate(View* view) const { | |
330 return !focus_restriction_ || focus_restriction_->Contains(view); | |
331 } | |
332 | |
333 View* focus_restriction_; | |
334 | |
335 DISALLOW_COPY_AND_ASSIGN(TestFocusRules); | |
336 }; | |
337 | |
338 // Common infrastructure shared by all FocusController test types. | |
339 class FocusControllerTestBase : public testing::Test { | |
340 protected: | |
341 // Hierarchy used by all tests: | |
342 // root_view | |
343 // +-- w1 | |
344 // | +-- w11 | |
345 // | +-- w12 | |
346 // +-- w2 | |
347 // | +-- w21 | |
348 // | +-- w211 | |
349 // +-- w3 | |
350 FocusControllerTestBase() | |
351 : root_view_(TestView::Build(0, gfx::Rect(0, 0, 800, 600))), | |
352 v1(TestView::Build(1, gfx::Rect(0, 0, 50, 50), root_view())), | |
353 v11(TestView::Build(11, gfx::Rect(5, 5, 10, 10), v1)), | |
354 v12(TestView::Build(12, gfx::Rect(15, 15, 10, 10), v1)), | |
355 v2(TestView::Build(2, gfx::Rect(75, 75, 50, 50), root_view())), | |
356 v21(TestView::Build(21, gfx::Rect(5, 5, 10, 10), v2)), | |
357 v211(TestView::Build(211, gfx::Rect(1, 1, 5, 5), v21)), | |
358 v3(TestView::Build(3, gfx::Rect(125, 125, 50, 50), root_view())) {} | |
359 | |
360 // Overridden from testing::Test: | |
361 void SetUp() override { | |
362 testing::Test::SetUp(); | |
363 | |
364 test_focus_rules_ = new TestFocusRules(root_view()); | |
365 focus_controller_.reset( | |
366 new FocusController(scoped_ptr<FocusRules>(test_focus_rules_))); | |
367 SetFocusController(root_view(), focus_controller_.get()); | |
368 | |
369 capture_controller_.reset(new CaptureController); | |
370 SetCaptureController(root_view(), capture_controller_.get()); | |
371 | |
372 ViewTarget* root_target = root_view_->target(); | |
373 root_target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); | |
374 view_event_dispatcher_.reset(new ViewEventDispatcher()); | |
375 view_event_dispatcher_->SetRootViewTarget(root_target); | |
376 | |
377 GetRootViewTarget()->AddPreTargetHandler(focus_controller_.get()); | |
378 } | |
379 | |
380 void TearDown() override { | |
381 GetRootViewTarget()->RemovePreTargetHandler(focus_controller_.get()); | |
382 view_event_dispatcher_.reset(); | |
383 | |
384 root_view_->Destroy(); | |
385 | |
386 capture_controller_.reset(); | |
387 test_focus_rules_ = nullptr; // Owned by FocusController. | |
388 focus_controller_.reset(); | |
389 | |
390 testing::Test::TearDown(); | |
391 } | |
392 | |
393 void FocusView(View* view) { focus_controller_->FocusView(view); } | |
394 View* GetFocusedView() { return focus_controller_->GetFocusedView(); } | |
395 int GetFocusedViewId() { | |
396 View* focused_view = GetFocusedView(); | |
397 return focused_view ? focused_view->id() : -1; | |
398 } | |
399 void ActivateView(View* view) { focus_controller_->ActivateView(view); } | |
400 void DeactivateView(View* view) { focus_controller_->DeactivateView(view); } | |
401 View* GetActiveView() { return focus_controller_->GetActiveView(); } | |
402 int GetActiveViewId() { | |
403 View* active_view = GetActiveView(); | |
404 return active_view ? active_view->id() : -1; | |
405 } | |
406 | |
407 View* GetViewById(int id) { return root_view_->GetChildById(id); } | |
408 | |
409 void ClickLeftButton(View* view) { | |
410 // Get the center bounds of |target| in |root_view_| coordinate space. | |
411 gfx::Point center = | |
412 gfx::Rect(view->bounds().To<gfx::Rect>().size()).CenterPoint(); | |
413 ViewTarget::ConvertPointToTarget(ViewTarget::TargetFromView(view), | |
414 root_view_->target(), ¢er); | |
415 | |
416 ui::MouseEvent button_down(ui::ET_MOUSE_PRESSED, center, center, | |
417 ui::EventTimeForNow(), | |
418 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_NONE); | |
419 ui::EventDispatchDetails details = | |
420 view_event_dispatcher_->OnEventFromSource(&button_down); | |
421 CHECK(!details.dispatcher_destroyed); | |
422 | |
423 ui::MouseEvent button_up(ui::ET_MOUSE_RELEASED, center, center, | |
424 ui::EventTimeForNow(), | |
425 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_NONE); | |
426 details = view_event_dispatcher_->OnEventFromSource(&button_up); | |
427 CHECK(!details.dispatcher_destroyed); | |
428 } | |
429 | |
430 ViewTarget* GetRootViewTarget() { | |
431 return ViewTarget::TargetFromView(root_view()); | |
432 } | |
433 | |
434 View* root_view() { return root_view_; } | |
435 TestFocusRules* test_focus_rules() { return test_focus_rules_; } | |
436 FocusController* focus_controller() { return focus_controller_.get(); } | |
437 CaptureController* capture_controller() { return capture_controller_.get(); } | |
438 | |
439 // Test functions. | |
440 virtual void BasicFocus() = 0; | |
441 virtual void BasicActivation() = 0; | |
442 virtual void FocusEvents() = 0; | |
443 virtual void DuplicateFocusEvents() {} | |
444 virtual void ActivationEvents() = 0; | |
445 virtual void ReactivationEvents() {} | |
446 virtual void DuplicateActivationEvents() {} | |
447 virtual void ShiftFocusWithinActiveView() {} | |
448 virtual void ShiftFocusToChildOfInactiveView() {} | |
449 virtual void ShiftFocusToParentOfFocusedView() {} | |
450 virtual void FocusRulesOverride() = 0; | |
451 virtual void ActivationRulesOverride() = 0; | |
452 virtual void ShiftFocusOnActivation() {} | |
453 virtual void ShiftFocusOnActivationDueToHide() {} | |
454 virtual void NoShiftActiveOnActivation() {} | |
455 virtual void ChangeFocusWhenNothingFocusedAndCaptured() {} | |
456 virtual void DontPassDestroyedView() {} | |
457 // TODO(erg): Also, void FocusedTextInputClient() once we build the IME. | |
458 | |
459 private: | |
460 TestView* root_view_; | |
461 scoped_ptr<FocusController> focus_controller_; | |
462 TestFocusRules* test_focus_rules_; | |
463 scoped_ptr<CaptureController> capture_controller_; | |
464 // TODO(erg): The aura version of this class also keeps track of WMState. Do | |
465 // we need something analogous here? | |
466 | |
467 scoped_ptr<ViewEventDispatcher> view_event_dispatcher_; | |
468 | |
469 TestView* v1; | |
470 TestView* v11; | |
471 TestView* v12; | |
472 TestView* v2; | |
473 TestView* v21; | |
474 TestView* v211; | |
475 TestView* v3; | |
476 | |
477 DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase); | |
478 }; | |
479 | |
480 // Test base for tests where focus is directly set to a target view. | |
481 class FocusControllerDirectTestBase : public FocusControllerTestBase { | |
482 protected: | |
483 FocusControllerDirectTestBase() {} | |
484 | |
485 // Different test types shift focus in different ways. | |
486 virtual void FocusViewDirect(View* view) = 0; | |
487 virtual void ActivateViewDirect(View* view) = 0; | |
488 virtual void DeactivateViewDirect(View* view) = 0; | |
489 | |
490 // Input events do not change focus if the view can not be focused. | |
491 virtual bool IsInputEvent() = 0; | |
492 | |
493 void FocusViewById(int id) { | |
494 View* view = root_view()->GetChildById(id); | |
495 DCHECK(view); | |
496 FocusViewDirect(view); | |
497 } | |
498 void ActivateViewById(int id) { | |
499 View* view = root_view()->GetChildById(id); | |
500 DCHECK(view); | |
501 ActivateViewDirect(view); | |
502 } | |
503 | |
504 // Overridden from FocusControllerTestBase: | |
505 void BasicFocus() override { | |
506 EXPECT_EQ(nullptr, GetFocusedView()); | |
507 FocusViewById(1); | |
508 EXPECT_EQ(1, GetFocusedViewId()); | |
509 FocusViewById(2); | |
510 EXPECT_EQ(2, GetFocusedViewId()); | |
511 } | |
512 void BasicActivation() override { | |
513 EXPECT_EQ(nullptr, GetActiveView()); | |
514 ActivateViewById(1); | |
515 EXPECT_EQ(1, GetActiveViewId()); | |
516 ActivateViewById(2); | |
517 EXPECT_EQ(2, GetActiveViewId()); | |
518 // Verify that attempting to deactivate NULL does not crash and does not | |
519 // change activation. | |
520 DeactivateView(nullptr); | |
521 EXPECT_EQ(2, GetActiveViewId()); | |
522 DeactivateView(GetActiveView()); | |
523 EXPECT_EQ(1, GetActiveViewId()); | |
524 } | |
525 void FocusEvents() override { | |
526 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
527 ScopedFilteringFocusNotificationObserver observer1( | |
528 focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); | |
529 ScopedFilteringFocusNotificationObserver observer2( | |
530 focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); | |
531 | |
532 { | |
533 SCOPED_TRACE("initial state"); | |
534 root_observer.ExpectCounts(0, 0); | |
535 observer1.ExpectCounts(0, 0); | |
536 observer2.ExpectCounts(0, 0); | |
537 } | |
538 | |
539 FocusViewById(1); | |
540 { | |
541 SCOPED_TRACE("FocusViewById(1)"); | |
542 root_observer.ExpectCounts(1, 1); | |
543 observer1.ExpectCounts(1, 1); | |
544 observer2.ExpectCounts(0, 0); | |
545 } | |
546 | |
547 FocusViewById(2); | |
548 { | |
549 SCOPED_TRACE("FocusViewById(2)"); | |
550 root_observer.ExpectCounts(2, 2); | |
551 observer1.ExpectCounts(2, 2); | |
552 observer2.ExpectCounts(1, 1); | |
553 } | |
554 } | |
555 void DuplicateFocusEvents() override { | |
556 // Focusing an existing focused view should not resend focus events. | |
557 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
558 ScopedFilteringFocusNotificationObserver observer1( | |
559 focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); | |
560 | |
561 root_observer.ExpectCounts(0, 0); | |
562 observer1.ExpectCounts(0, 0); | |
563 | |
564 FocusViewById(1); | |
565 root_observer.ExpectCounts(1, 1); | |
566 observer1.ExpectCounts(1, 1); | |
567 | |
568 FocusViewById(1); | |
569 root_observer.ExpectCounts(1, 1); | |
570 observer1.ExpectCounts(1, 1); | |
571 } | |
572 void ActivationEvents() override { | |
573 ActivateViewById(1); | |
574 | |
575 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
576 ScopedFilteringFocusNotificationObserver observer1( | |
577 focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); | |
578 ScopedFilteringFocusNotificationObserver observer2( | |
579 focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); | |
580 | |
581 root_observer.ExpectCounts(0, 0); | |
582 observer1.ExpectCounts(0, 0); | |
583 observer2.ExpectCounts(0, 0); | |
584 | |
585 ActivateViewById(2); | |
586 root_observer.ExpectCounts(1, 1); | |
587 observer1.ExpectCounts(1, 1); | |
588 observer2.ExpectCounts(1, 1); | |
589 } | |
590 void ReactivationEvents() override { | |
591 ActivateViewById(1); | |
592 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
593 EXPECT_EQ(0, root_observer.reactivation_count()); | |
594 GetViewById(2)->SetVisible(false); | |
595 // When we attempt to activate "2", which cannot be activated because it | |
596 // is not visible, "1" will be reactivated. | |
597 ActivateViewById(2); | |
598 EXPECT_EQ(1, root_observer.reactivation_count()); | |
599 EXPECT_EQ(GetViewById(2), | |
600 root_observer.reactivation_requested_view()); | |
601 EXPECT_EQ(GetViewById(1), | |
602 root_observer.reactivation_actual_view()); | |
603 } | |
604 void DuplicateActivationEvents() override { | |
605 ActivateViewById(1); | |
606 | |
607 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
608 ScopedFilteringFocusNotificationObserver observer1( | |
609 focus_controller(), GetViewById(1), GetActiveView(), GetFocusedView()); | |
610 ScopedFilteringFocusNotificationObserver observer2( | |
611 focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); | |
612 | |
613 root_observer.ExpectCounts(0, 0); | |
614 observer1.ExpectCounts(0, 0); | |
615 observer2.ExpectCounts(0, 0); | |
616 | |
617 ActivateViewById(2); | |
618 root_observer.ExpectCounts(1, 1); | |
619 observer1.ExpectCounts(1, 1); | |
620 observer2.ExpectCounts(1, 1); | |
621 | |
622 // Activating an existing active view should not resend activation events. | |
623 ActivateViewById(2); | |
624 root_observer.ExpectCounts(1, 1); | |
625 observer1.ExpectCounts(1, 1); | |
626 observer2.ExpectCounts(1, 1); | |
627 } | |
628 void ShiftFocusWithinActiveView() override { | |
629 ActivateViewById(1); | |
630 EXPECT_EQ(1, GetActiveViewId()); | |
631 EXPECT_EQ(1, GetFocusedViewId()); | |
632 FocusViewById(11); | |
633 EXPECT_EQ(11, GetFocusedViewId()); | |
634 FocusViewById(12); | |
635 EXPECT_EQ(12, GetFocusedViewId()); | |
636 } | |
637 void ShiftFocusToChildOfInactiveView() override { | |
638 ActivateViewById(2); | |
639 EXPECT_EQ(2, GetActiveViewId()); | |
640 EXPECT_EQ(2, GetFocusedViewId()); | |
641 FocusViewById(11); | |
642 EXPECT_EQ(1, GetActiveViewId()); | |
643 EXPECT_EQ(11, GetFocusedViewId()); | |
644 } | |
645 void ShiftFocusToParentOfFocusedView() override { | |
646 ActivateViewById(1); | |
647 EXPECT_EQ(1, GetFocusedViewId()); | |
648 FocusViewById(11); | |
649 EXPECT_EQ(11, GetFocusedViewId()); | |
650 FocusViewById(1); | |
651 // Focus should _not_ shift to the parent of the already-focused view. | |
652 EXPECT_EQ(11, GetFocusedViewId()); | |
653 } | |
654 void FocusRulesOverride() override { | |
655 EXPECT_EQ(NULL, GetFocusedView()); | |
656 FocusViewById(11); | |
657 EXPECT_EQ(11, GetFocusedViewId()); | |
658 | |
659 test_focus_rules()->set_focus_restriction(GetViewById(211)); | |
660 FocusViewById(12); | |
661 // Input events leave focus unchanged; direct API calls will change focus | |
662 // to the restricted view. | |
663 int focused_view = IsInputEvent() ? 11 : 211; | |
664 EXPECT_EQ(focused_view, GetFocusedViewId()); | |
665 | |
666 test_focus_rules()->set_focus_restriction(NULL); | |
667 FocusViewById(12); | |
668 EXPECT_EQ(12, GetFocusedViewId()); | |
669 } | |
670 void ActivationRulesOverride() override { | |
671 ActivateViewById(1); | |
672 EXPECT_EQ(1, GetActiveViewId()); | |
673 EXPECT_EQ(1, GetFocusedViewId()); | |
674 | |
675 View* v3 = GetViewById(3); | |
676 test_focus_rules()->set_focus_restriction(v3); | |
677 | |
678 ActivateViewById(2); | |
679 // Input events leave activation unchanged; direct API calls will activate | |
680 // the restricted view. | |
681 int active_view = IsInputEvent() ? 1 : 3; | |
682 EXPECT_EQ(active_view, GetActiveViewId()); | |
683 EXPECT_EQ(active_view, GetFocusedViewId()); | |
684 | |
685 test_focus_rules()->set_focus_restriction(NULL); | |
686 ActivateViewById(2); | |
687 EXPECT_EQ(2, GetActiveViewId()); | |
688 EXPECT_EQ(2, GetFocusedViewId()); | |
689 } | |
690 void ShiftFocusOnActivation() override { | |
691 // When a view is activated, by default that view is also focused. | |
692 // An ActivationChangeObserver may shift focus to another view within the | |
693 // same activatable view. | |
694 ActivateViewById(2); | |
695 EXPECT_EQ(2, GetFocusedViewId()); | |
696 ActivateViewById(1); | |
697 EXPECT_EQ(1, GetFocusedViewId()); | |
698 | |
699 ActivateViewById(2); | |
700 | |
701 View* target = GetViewById(1); | |
702 | |
703 scoped_ptr<FocusShiftingActivationObserver> observer( | |
704 new FocusShiftingActivationObserver(focus_controller(), target)); | |
705 observer->set_shift_focus_to(target->GetChildById(11)); | |
706 focus_controller()->AddObserver(observer.get()); | |
707 | |
708 ActivateViewById(1); | |
709 | |
710 // w1's ActivationChangeObserver shifted focus to this child, pre-empting | |
711 // FocusController's default setting. | |
712 EXPECT_EQ(11, GetFocusedViewId()); | |
713 | |
714 ActivateViewById(2); | |
715 EXPECT_EQ(2, GetFocusedViewId()); | |
716 | |
717 // Simulate a focus reset by the ActivationChangeObserver. This should | |
718 // trigger the default setting in FocusController. | |
719 observer->set_shift_focus_to(nullptr); | |
720 ActivateViewById(1); | |
721 EXPECT_EQ(1, GetFocusedViewId()); | |
722 | |
723 focus_controller()->RemoveObserver(observer.get()); | |
724 | |
725 ActivateViewById(2); | |
726 EXPECT_EQ(2, GetFocusedViewId()); | |
727 ActivateViewById(1); | |
728 EXPECT_EQ(1, GetFocusedViewId()); | |
729 } | |
730 void ShiftFocusOnActivationDueToHide() override { | |
731 // Similar to ShiftFocusOnActivation except the activation change is | |
732 // triggered by hiding the active view. | |
733 ActivateViewById(1); | |
734 EXPECT_EQ(1, GetFocusedViewId()); | |
735 | |
736 // Removes view 3 as candidate for next activatable view. | |
737 root_view()->GetChildById(3)->SetVisible(false); | |
738 EXPECT_EQ(1, GetFocusedViewId()); | |
739 | |
740 View* target = root_view()->GetChildById(2); | |
741 | |
742 scoped_ptr<FocusShiftingActivationObserver> observer( | |
743 new FocusShiftingActivationObserver(focus_controller(), target)); | |
744 observer->set_shift_focus_to(target->GetChildById(21)); | |
745 focus_controller()->AddObserver(observer.get()); | |
746 | |
747 // Hide the active view. | |
748 root_view()->GetChildById(1)->SetVisible(false); | |
749 | |
750 EXPECT_EQ(21, GetFocusedViewId()); | |
751 | |
752 focus_controller()->RemoveObserver(observer.get()); | |
753 } | |
754 void NoShiftActiveOnActivation() override { | |
755 // When a view is activated, we need to prevent any change to activation | |
756 // from being made in response to an activation change notification. | |
757 } | |
758 | |
759 // Verifies focus change is honored while capture held. | |
760 void ChangeFocusWhenNothingFocusedAndCaptured() override { | |
761 View* v1 = root_view()->GetChildById(1); | |
762 capture_controller()->SetCapture(v1); | |
763 | |
764 EXPECT_EQ(-1, GetActiveViewId()); | |
765 EXPECT_EQ(-1, GetFocusedViewId()); | |
766 | |
767 FocusViewById(1); | |
768 | |
769 EXPECT_EQ(1, GetActiveViewId()); | |
770 EXPECT_EQ(1, GetFocusedViewId()); | |
771 | |
772 capture_controller()->ReleaseCapture(v1); | |
773 } | |
774 | |
775 // Verifies if a view that loses activation or focus is destroyed during | |
776 // observer notification we don't pass the destroyed view to other observers. | |
777 void DontPassDestroyedView() override { | |
778 FocusViewById(1); | |
779 | |
780 EXPECT_EQ(1, GetActiveViewId()); | |
781 EXPECT_EQ(1, GetFocusedViewId()); | |
782 | |
783 { | |
784 View* to_destroy = root_view()->GetChildById(1); | |
785 DestroyOnLoseActivationFocusNotificationObserver observer1( | |
786 focus_controller(), to_destroy, GetActiveView()); | |
787 RecordingFocusNotificationObserver observer2(focus_controller(), | |
788 &observer1); | |
789 | |
790 FocusViewById(2); | |
791 | |
792 EXPECT_EQ(2, GetActiveViewId()); | |
793 EXPECT_EQ(2, GetFocusedViewId()); | |
794 | |
795 EXPECT_EQ(to_destroy, observer1.GetDestroyedView()); | |
796 EXPECT_FALSE(observer2.was_notified_with_destroyed_view()); | |
797 } | |
798 | |
799 { | |
800 View* to_destroy = root_view()->GetChildById(2); | |
801 DestroyOnLoseActivationFocusNotificationObserver observer1( | |
802 focus_controller(), to_destroy, GetActiveView()); | |
803 RecordingFocusNotificationObserver observer2(focus_controller(), | |
804 &observer1); | |
805 | |
806 FocusViewById(3); | |
807 | |
808 EXPECT_EQ(3, GetActiveViewId()); | |
809 EXPECT_EQ(3, GetFocusedViewId()); | |
810 | |
811 EXPECT_EQ(to_destroy, observer1.GetDestroyedView()); | |
812 EXPECT_FALSE(observer2.was_notified_with_destroyed_view()); | |
813 } | |
814 } | |
815 | |
816 private: | |
817 DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase); | |
818 }; | |
819 | |
820 // Focus and Activation changes via the FocusController API. | |
821 class FocusControllerApiTest : public FocusControllerDirectTestBase { | |
822 public: | |
823 FocusControllerApiTest() {} | |
824 | |
825 private: | |
826 // Overridden from FocusControllerTestBase: | |
827 void FocusViewDirect(View* view) override { FocusView(view); } | |
828 void ActivateViewDirect(View* view) override { ActivateView(view); } | |
829 void DeactivateViewDirect(View* view) override { DeactivateView(view); } | |
830 bool IsInputEvent() override { return false; } | |
831 | |
832 DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest); | |
833 }; | |
834 | |
835 // Focus and Activation changes via input events. | |
836 class FocusControllerMouseEventTest : public FocusControllerDirectTestBase { | |
837 public: | |
838 FocusControllerMouseEventTest() {} | |
839 | |
840 // Tests that a handled mouse event does not trigger a view activation. | |
841 void IgnoreHandledEvent() { | |
842 EXPECT_EQ(NULL, GetActiveView()); | |
843 View* v1 = root_view()->GetChildById(1); | |
844 SimpleEventHandler handler; | |
845 GetRootViewTarget()->PrependPreTargetHandler(&handler); | |
846 ClickLeftButton(v1); | |
847 EXPECT_EQ(NULL, GetActiveView()); | |
848 // TODO(erg): Add gesture testing when we get gestures working. | |
849 GetRootViewTarget()->RemovePreTargetHandler(&handler); | |
850 ClickLeftButton(v1); | |
851 EXPECT_EQ(1, GetActiveViewId()); | |
852 } | |
853 | |
854 private: | |
855 // Overridden from FocusControllerTestBase: | |
856 void FocusViewDirect(View* view) override { ClickLeftButton(view); } | |
857 void ActivateViewDirect(View* view) override { ClickLeftButton(view); } | |
858 void DeactivateViewDirect(View* view) override { | |
859 View* next_activatable = test_focus_rules()->GetNextActivatableView(view); | |
860 ClickLeftButton(next_activatable); | |
861 } | |
862 bool IsInputEvent() override { return true; } | |
863 | |
864 DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest); | |
865 }; | |
866 | |
867 // TODO(erg): Add a FocusControllerGestureEventTest once we have working | |
868 // gesture forwarding and handling. | |
869 | |
870 // Test base for tests where focus is implicitly set to a window as the result | |
871 // of a disposition change to the focused window or the hierarchy that contains | |
872 // it. | |
873 class FocusControllerImplicitTestBase : public FocusControllerTestBase { | |
874 protected: | |
875 explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {} | |
876 | |
877 View* GetDispositionView(View* view) { | |
878 return parent_ ? view->parent() : view; | |
879 } | |
880 | |
881 // Change the disposition of |view| in such a way as it will lose focus. | |
882 virtual void ChangeViewDisposition(View* view) = 0; | |
883 | |
884 // Allow each disposition change test to add additional post-disposition | |
885 // change expectations. | |
886 virtual void PostDispostionChangeExpectations() {} | |
887 | |
888 // Overridden from FocusControllerTestBase: | |
889 void BasicFocus() override { | |
890 EXPECT_EQ(NULL, GetFocusedView()); | |
891 | |
892 View* w211 = root_view()->GetChildById(211); | |
893 FocusView(w211); | |
894 EXPECT_EQ(211, GetFocusedViewId()); | |
895 | |
896 ChangeViewDisposition(w211); | |
897 // BasicFocusRules passes focus to the parent. | |
898 EXPECT_EQ(parent_ ? 2 : 21, GetFocusedViewId()); | |
899 } | |
900 | |
901 void BasicActivation() override { | |
902 DCHECK(!parent_) << "Activation tests don't support parent changes."; | |
903 | |
904 EXPECT_EQ(NULL, GetActiveView()); | |
905 | |
906 View* w2 = root_view()->GetChildById(2); | |
907 ActivateView(w2); | |
908 EXPECT_EQ(2, GetActiveViewId()); | |
909 | |
910 ChangeViewDisposition(w2); | |
911 EXPECT_EQ(3, GetActiveViewId()); | |
912 PostDispostionChangeExpectations(); | |
913 } | |
914 | |
915 void FocusEvents() override { | |
916 View* w211 = root_view()->GetChildById(211); | |
917 FocusView(w211); | |
918 | |
919 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
920 ScopedFilteringFocusNotificationObserver observer211( | |
921 focus_controller(), GetViewById(211), GetActiveView(), | |
922 GetFocusedView()); | |
923 | |
924 { | |
925 SCOPED_TRACE("first"); | |
926 root_observer.ExpectCounts(0, 0); | |
927 observer211.ExpectCounts(0, 0); | |
928 } | |
929 | |
930 ChangeViewDisposition(w211); | |
931 { | |
932 SCOPED_TRACE("second"); | |
933 { | |
934 SCOPED_TRACE("root_observer"); | |
935 root_observer.ExpectCounts(0, 1); | |
936 } | |
937 { | |
938 SCOPED_TRACE("observer211"); | |
939 observer211.ExpectCounts(0, 1); | |
940 } | |
941 } | |
942 } | |
943 | |
944 void ActivationEvents() override { | |
945 DCHECK(!parent_) << "Activation tests don't support parent changes."; | |
946 | |
947 View* w2 = root_view()->GetChildById(2); | |
948 ActivateView(w2); | |
949 | |
950 ScopedFocusNotificationObserver root_observer(focus_controller()); | |
951 ScopedFilteringFocusNotificationObserver observer2( | |
952 focus_controller(), GetViewById(2), GetActiveView(), GetFocusedView()); | |
953 ScopedFilteringFocusNotificationObserver observer3( | |
954 focus_controller(), GetViewById(3), GetActiveView(), GetFocusedView()); | |
955 root_observer.ExpectCounts(0, 0); | |
956 observer2.ExpectCounts(0, 0); | |
957 observer3.ExpectCounts(0, 0); | |
958 | |
959 ChangeViewDisposition(w2); | |
960 root_observer.ExpectCounts(1, 1); | |
961 observer2.ExpectCounts(1, 1); | |
962 observer3.ExpectCounts(1, 1); | |
963 } | |
964 | |
965 void FocusRulesOverride() override { | |
966 EXPECT_EQ(NULL, GetFocusedView()); | |
967 View* w211 = root_view()->GetChildById(211); | |
968 FocusView(w211); | |
969 EXPECT_EQ(211, GetFocusedViewId()); | |
970 | |
971 test_focus_rules()->set_focus_restriction(root_view()->GetChildById(11)); | |
972 ChangeViewDisposition(w211); | |
973 // Normally, focus would shift to the parent (w21) but the override shifts | |
974 // it to 11. | |
975 EXPECT_EQ(11, GetFocusedViewId()); | |
976 | |
977 test_focus_rules()->set_focus_restriction(NULL); | |
978 } | |
979 | |
980 void ActivationRulesOverride() override { | |
981 DCHECK(!parent_) << "Activation tests don't support parent changes."; | |
982 | |
983 View* w1 = root_view()->GetChildById(1); | |
984 ActivateView(w1); | |
985 | |
986 EXPECT_EQ(1, GetActiveViewId()); | |
987 EXPECT_EQ(1, GetFocusedViewId()); | |
988 | |
989 View* w3 = root_view()->GetChildById(3); | |
990 test_focus_rules()->set_focus_restriction(w3); | |
991 | |
992 // Normally, activation/focus would move to w2, but since we have a focus | |
993 // restriction, it should move to w3 instead. | |
994 ChangeViewDisposition(w1); | |
995 EXPECT_EQ(3, GetActiveViewId()); | |
996 EXPECT_EQ(3, GetFocusedViewId()); | |
997 | |
998 test_focus_rules()->set_focus_restriction(NULL); | |
999 ActivateView(root_view()->GetChildById(2)); | |
1000 EXPECT_EQ(2, GetActiveViewId()); | |
1001 EXPECT_EQ(2, GetFocusedViewId()); | |
1002 } | |
1003 | |
1004 private: | |
1005 // When true, the disposition change occurs to the parent of the window | |
1006 // instead of to the window. This verifies that changes occurring in the | |
1007 // hierarchy that contains the window affect the window's focus. | |
1008 bool parent_; | |
1009 | |
1010 DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase); | |
1011 }; | |
1012 | |
1013 // Focus and Activation changes in response to window visibility changes. | |
1014 class FocusControllerHideTest : public FocusControllerImplicitTestBase { | |
1015 public: | |
1016 FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {} | |
1017 | |
1018 protected: | |
1019 FocusControllerHideTest(bool parent) | |
1020 : FocusControllerImplicitTestBase(parent) {} | |
1021 | |
1022 // Overridden from FocusControllerImplicitTestBase: | |
1023 void ChangeViewDisposition(View* view) override { | |
1024 GetDispositionView(view)->SetVisible(false); | |
1025 } | |
1026 | |
1027 private: | |
1028 DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest); | |
1029 }; | |
1030 | |
1031 // Focus and Activation changes in response to window parent visibility | |
1032 // changes. | |
1033 class FocusControllerParentHideTest : public FocusControllerHideTest { | |
1034 public: | |
1035 FocusControllerParentHideTest() : FocusControllerHideTest(true) {} | |
1036 | |
1037 private: | |
1038 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest); | |
1039 }; | |
1040 | |
1041 // Focus and Activation changes in response to window destruction. | |
1042 class FocusControllerDestructionTest : public FocusControllerImplicitTestBase { | |
1043 public: | |
1044 FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {} | |
1045 | |
1046 protected: | |
1047 FocusControllerDestructionTest(bool parent) | |
1048 : FocusControllerImplicitTestBase(parent) {} | |
1049 | |
1050 // Overridden from FocusControllerImplicitTestBase: | |
1051 void ChangeViewDisposition(View* view) override { | |
1052 GetDispositionView(view)->Destroy(); | |
1053 } | |
1054 | |
1055 private: | |
1056 DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest); | |
1057 }; | |
1058 | |
1059 // Focus and Activation changes in response to window removal. | |
1060 class FocusControllerRemovalTest : public FocusControllerImplicitTestBase { | |
1061 public: | |
1062 FocusControllerRemovalTest() | |
1063 : FocusControllerImplicitTestBase(false), | |
1064 window_to_destroy_(nullptr) {} | |
1065 | |
1066 protected: | |
1067 FocusControllerRemovalTest(bool parent) | |
1068 : FocusControllerImplicitTestBase(parent), | |
1069 window_to_destroy_(nullptr) {} | |
1070 | |
1071 // Overridden from FocusControllerImplicitTestBase: | |
1072 void ChangeViewDisposition(View* view) override { | |
1073 View* disposition_view = GetDispositionView(view); | |
1074 disposition_view->parent()->RemoveChild(disposition_view); | |
1075 window_to_destroy_ = disposition_view; | |
1076 } | |
1077 void TearDown() override { | |
1078 if (window_to_destroy_) | |
1079 window_to_destroy_->Destroy(); | |
1080 | |
1081 FocusControllerImplicitTestBase::TearDown(); | |
1082 } | |
1083 | |
1084 private: | |
1085 View* window_to_destroy_; | |
1086 | |
1087 DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest); | |
1088 }; | |
1089 | |
1090 // Focus and Activation changes in response to window parent removal. | |
1091 class FocusControllerParentRemovalTest : public FocusControllerRemovalTest { | |
1092 public: | |
1093 FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {} | |
1094 | |
1095 private: | |
1096 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest); | |
1097 }; | |
1098 | |
1099 #define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \ | |
1100 TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); } | |
1101 | |
1102 // Runs direct focus change tests (input events and API calls). | |
1103 // | |
1104 // TODO(erg): Enable gesture events in the future. | |
1105 #define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ | |
1106 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \ | |
1107 FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) | |
1108 | |
1109 // Runs implicit focus change tests for disposition changes to target. | |
1110 #define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \ | |
1111 FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \ | |
1112 FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \ | |
1113 FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME) | |
1114 | |
1115 // Runs implicit focus change tests for disposition changes to target's parent | |
1116 // hierarchy. | |
1117 #define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \ | |
1118 FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \ | |
1119 FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME) | |
1120 // TODO(erg): FocusControllerParentDestructionTest were commented out in the | |
1121 // aura version of this file, and don't work when I tried porting things over. | |
1122 | |
1123 // Runs all implicit focus change tests (changes to the target and target's | |
1124 // parent hierarchy) | |
1125 #define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \ | |
1126 IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \ | |
1127 IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) | |
1128 | |
1129 // Runs all possible focus change tests. | |
1130 #define ALL_FOCUS_TESTS(TESTNAME) \ | |
1131 DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ | |
1132 IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) | |
1133 | |
1134 // Runs focus change tests that apply only to the target. For example, | |
1135 // implicit activation changes caused by window disposition changes do not | |
1136 // occur when changes to the containing hierarchy happen. | |
1137 #define TARGET_FOCUS_TESTS(TESTNAME) \ | |
1138 DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ | |
1139 IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) | |
1140 | |
1141 // - Focuses a window, verifies that focus changed. | |
1142 ALL_FOCUS_TESTS(BasicFocus); | |
1143 | |
1144 // - Activates a window, verifies that activation changed. | |
1145 TARGET_FOCUS_TESTS(BasicActivation); | |
1146 | |
1147 // - Focuses a window, verifies that focus events were dispatched. | |
1148 ALL_FOCUS_TESTS(FocusEvents); | |
1149 | |
1150 // - Focuses or activates a window multiple times, verifies that events are only | |
1151 // dispatched when focus/activation actually changes. | |
1152 DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents); | |
1153 DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents); | |
1154 | |
1155 // - Activates a window, verifies that activation events were dispatched. | |
1156 TARGET_FOCUS_TESTS(ActivationEvents); | |
1157 | |
1158 // - Attempts to active a hidden view, verifies that current view is | |
1159 // attempted to be reactivated and the appropriate event dispatched. | |
1160 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents); | |
1161 | |
1162 // - Input events/API calls shift focus between focusable views within the | |
1163 // active view. | |
1164 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveView); | |
1165 | |
1166 // - Input events/API calls to a child view of an inactive view shifts | |
1167 // activation to the activatable parent and focuses the child. | |
1168 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveView); | |
1169 | |
1170 // - Input events/API calls to focus the parent of the focused view do not | |
1171 // shift focus away from the child. | |
1172 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedView); | |
1173 | |
1174 // - Verifies that FocusRules determine what can be focused. | |
1175 ALL_FOCUS_TESTS(FocusRulesOverride); | |
1176 | |
1177 // - Verifies that FocusRules determine what can be activated. | |
1178 TARGET_FOCUS_TESTS(ActivationRulesOverride); | |
1179 | |
1180 // - Verifies that attempts to change focus or activation from a focus or | |
1181 // activation change observer are ignored. | |
1182 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation); | |
1183 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide); | |
1184 DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation); | |
1185 | |
1186 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, | |
1187 ChangeFocusWhenNothingFocusedAndCaptured); | |
1188 | |
1189 // See description above DontPassDestroyedView() for details. | |
1190 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDestroyedView); | |
1191 | |
1192 // TODO(erg): Add the TextInputClient tests here. | |
1193 | |
1194 // If a mouse event was handled, it should not activate a view. | |
1195 FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, IgnoreHandledEvent); | |
1196 | |
1197 } // namespace window_manager | |
OLD | NEW |