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.
5 #include "ui/wm/core/focus_controller.h"
9 #include "ui/aura/client/aura_constants.h"
10 #include "ui/aura/client/default_capture_client.h"
11 #include "ui/aura/client/focus_change_observer.h"
12 #include "ui/aura/test/aura_test_base.h"
13 #include "ui/aura/test/event_generator.h"
14 #include "ui/aura/test/test_window_delegate.h"
15 #include "ui/aura/test/test_windows.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/aura/window_tracker.h"
19 #include "ui/events/event_handler.h"
20 #include "ui/wm/core/base_focus_rules.h"
21 #include "ui/wm/core/wm_state.h"
22 #include "ui/wm/public/activation_change_observer.h"
23 #include "ui/wm/public/activation_client.h"
27 class FocusNotificationObserver : public aura::client::ActivationChangeObserver,
28 public aura::client::FocusChangeObserver {
30 FocusNotificationObserver()
31 : activation_changed_count_(0),
32 focus_changed_count_(0),
33 reactivation_count_(0),
34 reactivation_requested_window_(NULL),
35 reactivation_actual_window_(NULL) {}
36 virtual ~FocusNotificationObserver() {}
38 void ExpectCounts(int activation_changed_count, int focus_changed_count) {
39 EXPECT_EQ(activation_changed_count, activation_changed_count_);
40 EXPECT_EQ(focus_changed_count, focus_changed_count_);
42 int reactivation_count() const {
43 return reactivation_count_;
45 aura::Window* reactivation_requested_window() const {
46 return reactivation_requested_window_;
48 aura::Window* reactivation_actual_window() const {
49 return reactivation_actual_window_;
53 // Overridden from aura::client::ActivationChangeObserver:
54 virtual void OnWindowActivated(aura::Window* gained_active,
55 aura::Window* lost_active) OVERRIDE {
56 ++activation_changed_count_;
58 virtual void OnAttemptToReactivateWindow(
59 aura::Window* request_active,
60 aura::Window* actual_active) OVERRIDE {
61 ++reactivation_count_;
62 reactivation_requested_window_ = request_active;
63 reactivation_actual_window_ = actual_active;
66 // Overridden from aura::client::FocusChangeObserver:
67 virtual void OnWindowFocused(aura::Window* gained_focus,
68 aura::Window* lost_focus) OVERRIDE {
69 ++focus_changed_count_;
72 int activation_changed_count_;
73 int focus_changed_count_;
74 int reactivation_count_;
75 aura::Window* reactivation_requested_window_;
76 aura::Window* reactivation_actual_window_;
78 DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver);
83 virtual aura::Window* GetDeletedWindow() = 0;
86 virtual ~WindowDeleter() {}
89 // ActivationChangeObserver and FocusChangeObserver that keeps track of whether
90 // it was notified about activation changes or focus changes with a deleted
92 class RecordingActivationAndFocusChangeObserver
93 : public aura::client::ActivationChangeObserver,
94 public aura::client::FocusChangeObserver {
96 RecordingActivationAndFocusChangeObserver(aura::Window* root,
97 WindowDeleter* deleter)
100 was_notified_with_deleted_window_(false) {
101 aura::client::GetActivationClient(root_)->AddObserver(this);
102 aura::client::GetFocusClient(root_)->AddObserver(this);
104 virtual ~RecordingActivationAndFocusChangeObserver() {
105 aura::client::GetActivationClient(root_)->RemoveObserver(this);
106 aura::client::GetFocusClient(root_)->RemoveObserver(this);
109 bool was_notified_with_deleted_window() const {
110 return was_notified_with_deleted_window_;
113 // Overridden from aura::client::ActivationChangeObserver:
114 virtual void OnWindowActivated(aura::Window* gained_active,
115 aura::Window* lost_active) OVERRIDE {
116 if (lost_active && lost_active == deleter_->GetDeletedWindow())
117 was_notified_with_deleted_window_ = true;
120 // Overridden from aura::client::FocusChangeObserver:
121 virtual void OnWindowFocused(aura::Window* gained_focus,
122 aura::Window* lost_focus) OVERRIDE {
123 if (lost_focus && lost_focus == deleter_->GetDeletedWindow())
124 was_notified_with_deleted_window_ = true;
131 WindowDeleter* deleter_;
133 // Whether the observer was notified about the loss of activation or the
134 // loss of focus with a window already deleted by |deleter_| as the
135 // |lost_active| or |lost_focus| parameter.
136 bool was_notified_with_deleted_window_;
138 DISALLOW_COPY_AND_ASSIGN(RecordingActivationAndFocusChangeObserver);
141 // ActivationChangeObserver that deletes the window losing activation.
142 class DeleteOnLoseActivationChangeObserver :
143 public aura::client::ActivationChangeObserver,
144 public WindowDeleter {
146 explicit DeleteOnLoseActivationChangeObserver(aura::Window* window)
147 : root_(window->GetRootWindow()),
150 aura::client::GetActivationClient(root_)->AddObserver(this);
152 virtual ~DeleteOnLoseActivationChangeObserver() {
153 aura::client::GetActivationClient(root_)->RemoveObserver(this);
156 // Overridden from aura::client::ActivationChangeObserver:
157 virtual void OnWindowActivated(aura::Window* gained_active,
158 aura::Window* lost_active) OVERRIDE {
159 if (window_ && lost_active == window_) {
165 // Overridden from WindowDeleter:
166 virtual aura::Window* GetDeletedWindow() OVERRIDE {
167 return did_delete_ ? window_ : NULL;
172 aura::Window* window_;
175 DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseActivationChangeObserver);
178 // FocusChangeObserver that deletes the window losing focus.
179 class DeleteOnLoseFocusChangeObserver
180 : public aura::client::FocusChangeObserver,
181 public WindowDeleter {
183 explicit DeleteOnLoseFocusChangeObserver(aura::Window* window)
184 : root_(window->GetRootWindow()),
187 aura::client::GetFocusClient(root_)->AddObserver(this);
189 virtual ~DeleteOnLoseFocusChangeObserver() {
190 aura::client::GetFocusClient(root_)->RemoveObserver(this);
193 // Overridden from aura::client::FocusChangeObserver:
194 virtual void OnWindowFocused(aura::Window* gained_focus,
195 aura::Window* lost_focus) OVERRIDE {
196 if (window_ && lost_focus == window_) {
202 // Overridden from WindowDeleter:
203 virtual aura::Window* GetDeletedWindow() OVERRIDE {
204 return did_delete_ ? window_ : NULL;
209 aura::Window* window_;
212 DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseFocusChangeObserver);
215 class ScopedFocusNotificationObserver : public FocusNotificationObserver {
217 ScopedFocusNotificationObserver(aura::Window* root_window)
218 : root_window_(root_window) {
219 aura::client::GetActivationClient(root_window_)->AddObserver(this);
220 aura::client::GetFocusClient(root_window_)->AddObserver(this);
222 virtual ~ScopedFocusNotificationObserver() {
223 aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
224 aura::client::GetFocusClient(root_window_)->RemoveObserver(this);
228 aura::Window* root_window_;
230 DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver);
233 class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver {
235 ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id)
236 : target_(root_window->GetChildById(id)) {
237 aura::client::SetActivationChangeObserver(target_, this);
238 aura::client::SetFocusChangeObserver(target_, this);
239 tracker_.Add(target_);
241 virtual ~ScopedTargetFocusNotificationObserver() {
242 if (tracker_.Contains(target_)) {
243 aura::client::SetActivationChangeObserver(target_, NULL);
244 aura::client::SetFocusChangeObserver(target_, NULL);
249 aura::Window* target_;
250 aura::WindowTracker tracker_;
252 DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver);
255 class FocusShiftingActivationObserver
256 : public aura::client::ActivationChangeObserver {
258 explicit FocusShiftingActivationObserver(aura::Window* activated_window)
259 : activated_window_(activated_window),
260 shift_focus_to_(NULL) {}
261 virtual ~FocusShiftingActivationObserver() {}
263 void set_shift_focus_to(aura::Window* shift_focus_to) {
264 shift_focus_to_ = shift_focus_to;
268 // Overridden from aura::client::ActivationChangeObserver:
269 virtual void OnWindowActivated(aura::Window* gained_active,
270 aura::Window* lost_active) OVERRIDE {
271 // Shift focus to a child. This should prevent the default focusing from
272 // occurring in FocusController::FocusWindow().
273 if (gained_active == activated_window_) {
274 aura::client::FocusClient* client =
275 aura::client::GetFocusClient(gained_active);
276 client->FocusWindow(shift_focus_to_);
280 aura::Window* activated_window_;
281 aura::Window* shift_focus_to_;
283 DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver);
286 // BaseFocusRules subclass that allows basic overrides of focus/activation to
287 // be tested. This is intended more as a test that the override system works at
288 // all, rather than as an exhaustive set of use cases, those should be covered
289 // in tests for those FocusRules implementations.
290 class TestFocusRules : public BaseFocusRules {
292 TestFocusRules() : focus_restriction_(NULL) {}
294 // Restricts focus and activation to this window and its child hierarchy.
295 void set_focus_restriction(aura::Window* focus_restriction) {
296 focus_restriction_ = focus_restriction;
299 // Overridden from BaseFocusRules:
300 virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
301 // In FocusControllerTests, only the RootWindow has activatable children.
302 return window->GetRootWindow() == window;
304 virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE {
305 // Restricting focus to a non-activatable child window means the activatable
306 // parent outside the focus restriction is activatable.
308 CanFocusOrActivate(window) || window->Contains(focus_restriction_);
309 return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
311 virtual bool CanFocusWindow(aura::Window* window) const OVERRIDE {
312 return CanFocusOrActivate(window) ?
313 BaseFocusRules::CanFocusWindow(window) : false;
315 virtual aura::Window* GetActivatableWindow(
316 aura::Window* window) const OVERRIDE {
317 return BaseFocusRules::GetActivatableWindow(
318 CanFocusOrActivate(window) ? window : focus_restriction_);
320 virtual aura::Window* GetFocusableWindow(
321 aura::Window* window) const OVERRIDE {
322 return BaseFocusRules::GetFocusableWindow(
323 CanFocusOrActivate(window) ? window : focus_restriction_);
325 virtual aura::Window* GetNextActivatableWindow(
326 aura::Window* ignore) const OVERRIDE {
327 aura::Window* next_activatable =
328 BaseFocusRules::GetNextActivatableWindow(ignore);
329 return CanFocusOrActivate(next_activatable) ?
330 next_activatable : GetActivatableWindow(focus_restriction_);
334 bool CanFocusOrActivate(aura::Window* window) const {
335 return !focus_restriction_ || focus_restriction_->Contains(window);
338 aura::Window* focus_restriction_;
340 DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
343 // Common infrastructure shared by all FocusController test types.
344 class FocusControllerTestBase : public aura::test::AuraTestBase {
346 FocusControllerTestBase() {}
348 // Overridden from aura::test::AuraTestBase:
349 virtual void SetUp() OVERRIDE {
350 wm_state_.reset(new wm::WMState);
351 // FocusController registers itself as an Env observer so it can catch all
352 // window initializations, including the root_window()'s, so we create it
353 // before allowing the base setup.
354 test_focus_rules_ = new TestFocusRules;
355 focus_controller_.reset(new FocusController(test_focus_rules_));
356 aura::test::AuraTestBase::SetUp();
357 root_window()->AddPreTargetHandler(focus_controller_.get());
358 aura::client::SetFocusClient(root_window(), focus_controller_.get());
359 aura::client::SetActivationClient(root_window(), focus_controller_.get());
361 // Hierarchy used by all tests:
370 aura::Window* w1 = aura::test::CreateTestWindowWithDelegate(
371 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1,
372 gfx::Rect(0, 0, 50, 50), root_window());
373 aura::test::CreateTestWindowWithDelegate(
374 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 11,
375 gfx::Rect(5, 5, 10, 10), w1);
376 aura::test::CreateTestWindowWithDelegate(
377 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 12,
378 gfx::Rect(15, 15, 10, 10), w1);
379 aura::Window* w2 = aura::test::CreateTestWindowWithDelegate(
380 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 2,
381 gfx::Rect(75, 75, 50, 50), root_window());
382 aura::Window* w21 = aura::test::CreateTestWindowWithDelegate(
383 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 21,
384 gfx::Rect(5, 5, 10, 10), w2);
385 aura::test::CreateTestWindowWithDelegate(
386 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 211,
387 gfx::Rect(1, 1, 5, 5), w21);
388 aura::test::CreateTestWindowWithDelegate(
389 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 3,
390 gfx::Rect(125, 125, 50, 50), root_window());
392 virtual void TearDown() OVERRIDE {
393 root_window()->RemovePreTargetHandler(focus_controller_.get());
394 aura::test::AuraTestBase::TearDown();
395 test_focus_rules_ = NULL; // Owned by FocusController.
396 focus_controller_.reset();
400 void FocusWindow(aura::Window* window) {
401 aura::client::GetFocusClient(root_window())->FocusWindow(window);
403 aura::Window* GetFocusedWindow() {
404 return aura::client::GetFocusClient(root_window())->GetFocusedWindow();
406 int GetFocusedWindowId() {
407 aura::Window* focused_window = GetFocusedWindow();
408 return focused_window ? focused_window->id() : -1;
410 void ActivateWindow(aura::Window* window) {
411 aura::client::GetActivationClient(root_window())->ActivateWindow(window);
413 void DeactivateWindow(aura::Window* window) {
414 aura::client::GetActivationClient(root_window())->DeactivateWindow(window);
416 aura::Window* GetActiveWindow() {
417 return aura::client::GetActivationClient(root_window())->GetActiveWindow();
419 int GetActiveWindowId() {
420 aura::Window* active_window = GetActiveWindow();
421 return active_window ? active_window->id() : -1;
424 TestFocusRules* test_focus_rules() { return test_focus_rules_; }
427 virtual void BasicFocus() = 0;
428 virtual void BasicActivation() = 0;
429 virtual void FocusEvents() = 0;
430 virtual void DuplicateFocusEvents() {}
431 virtual void ActivationEvents() = 0;
432 virtual void ReactivationEvents() {}
433 virtual void DuplicateActivationEvents() {}
434 virtual void ShiftFocusWithinActiveWindow() {}
435 virtual void ShiftFocusToChildOfInactiveWindow() {}
436 virtual void ShiftFocusToParentOfFocusedWindow() {}
437 virtual void FocusRulesOverride() = 0;
438 virtual void ActivationRulesOverride() = 0;
439 virtual void ShiftFocusOnActivation() {}
440 virtual void ShiftFocusOnActivationDueToHide() {}
441 virtual void NoShiftActiveOnActivation() {}
442 virtual void NoFocusChangeOnClickOnCaptureWindow() {}
443 virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
444 virtual void DontPassDeletedWindow() {}
447 scoped_ptr<FocusController> focus_controller_;
448 TestFocusRules* test_focus_rules_;
449 scoped_ptr<wm::WMState> wm_state_;
451 DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase);
454 // Test base for tests where focus is directly set to a target window.
455 class FocusControllerDirectTestBase : public FocusControllerTestBase {
457 FocusControllerDirectTestBase() {}
459 // Different test types shift focus in different ways.
460 virtual void FocusWindowDirect(aura::Window* window) = 0;
461 virtual void ActivateWindowDirect(aura::Window* window) = 0;
462 virtual void DeactivateWindowDirect(aura::Window* window) = 0;
464 // Input events do not change focus if the window can not be focused.
465 virtual bool IsInputEvent() = 0;
467 void FocusWindowById(int id) {
468 aura::Window* window = root_window()->GetChildById(id);
470 FocusWindowDirect(window);
472 void ActivateWindowById(int id) {
473 aura::Window* window = root_window()->GetChildById(id);
475 ActivateWindowDirect(window);
478 // Overridden from FocusControllerTestBase:
479 virtual void BasicFocus() OVERRIDE {
480 EXPECT_EQ(NULL, GetFocusedWindow());
482 EXPECT_EQ(1, GetFocusedWindowId());
484 EXPECT_EQ(2, GetFocusedWindowId());
486 virtual void BasicActivation() OVERRIDE {
487 EXPECT_EQ(NULL, GetActiveWindow());
488 ActivateWindowById(1);
489 EXPECT_EQ(1, GetActiveWindowId());
490 ActivateWindowById(2);
491 EXPECT_EQ(2, GetActiveWindowId());
492 // Verify that attempting to deactivate NULL does not crash and does not
493 // change activation.
494 DeactivateWindow(NULL);
495 EXPECT_EQ(2, GetActiveWindowId());
496 DeactivateWindow(GetActiveWindow());
497 EXPECT_EQ(1, GetActiveWindowId());
499 virtual void FocusEvents() OVERRIDE {
500 ScopedFocusNotificationObserver root_observer(root_window());
501 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
502 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
504 root_observer.ExpectCounts(0, 0);
505 observer1.ExpectCounts(0, 0);
506 observer2.ExpectCounts(0, 0);
509 root_observer.ExpectCounts(1, 1);
510 observer1.ExpectCounts(1, 1);
511 observer2.ExpectCounts(0, 0);
514 root_observer.ExpectCounts(2, 2);
515 observer1.ExpectCounts(2, 2);
516 observer2.ExpectCounts(1, 1);
518 virtual void DuplicateFocusEvents() OVERRIDE {
519 // Focusing an existing focused window should not resend focus events.
520 ScopedFocusNotificationObserver root_observer(root_window());
521 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
523 root_observer.ExpectCounts(0, 0);
524 observer1.ExpectCounts(0, 0);
527 root_observer.ExpectCounts(1, 1);
528 observer1.ExpectCounts(1, 1);
531 root_observer.ExpectCounts(1, 1);
532 observer1.ExpectCounts(1, 1);
534 virtual void ActivationEvents() OVERRIDE {
535 ActivateWindowById(1);
537 ScopedFocusNotificationObserver root_observer(root_window());
538 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
539 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
541 root_observer.ExpectCounts(0, 0);
542 observer1.ExpectCounts(0, 0);
543 observer2.ExpectCounts(0, 0);
545 ActivateWindowById(2);
546 root_observer.ExpectCounts(1, 1);
547 observer1.ExpectCounts(1, 1);
548 observer2.ExpectCounts(1, 1);
550 virtual void ReactivationEvents() OVERRIDE {
551 ActivateWindowById(1);
552 ScopedFocusNotificationObserver root_observer(root_window());
553 EXPECT_EQ(0, root_observer.reactivation_count());
554 root_window()->GetChildById(2)->Hide();
555 // When we attempt to activate "2", which cannot be activated because it
556 // is not visible, "1" will be reactivated.
557 ActivateWindowById(2);
558 EXPECT_EQ(1, root_observer.reactivation_count());
559 EXPECT_EQ(root_window()->GetChildById(2),
560 root_observer.reactivation_requested_window());
561 EXPECT_EQ(root_window()->GetChildById(1),
562 root_observer.reactivation_actual_window());
564 virtual void DuplicateActivationEvents() OVERRIDE {
565 // Activating an existing active window should not resend activation events.
566 ActivateWindowById(1);
568 ScopedFocusNotificationObserver root_observer(root_window());
569 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
570 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
572 root_observer.ExpectCounts(0, 0);
573 observer1.ExpectCounts(0, 0);
574 observer2.ExpectCounts(0, 0);
576 ActivateWindowById(2);
577 root_observer.ExpectCounts(1, 1);
578 observer1.ExpectCounts(1, 1);
579 observer2.ExpectCounts(1, 1);
581 ActivateWindowById(2);
582 root_observer.ExpectCounts(1, 1);
583 observer1.ExpectCounts(1, 1);
584 observer2.ExpectCounts(1, 1);
586 virtual void ShiftFocusWithinActiveWindow() OVERRIDE {
587 ActivateWindowById(1);
588 EXPECT_EQ(1, GetActiveWindowId());
589 EXPECT_EQ(1, GetFocusedWindowId());
591 EXPECT_EQ(11, GetFocusedWindowId());
593 EXPECT_EQ(12, GetFocusedWindowId());
595 virtual void ShiftFocusToChildOfInactiveWindow() OVERRIDE {
596 ActivateWindowById(2);
597 EXPECT_EQ(2, GetActiveWindowId());
598 EXPECT_EQ(2, GetFocusedWindowId());
600 EXPECT_EQ(1, GetActiveWindowId());
601 EXPECT_EQ(11, GetFocusedWindowId());
603 virtual void ShiftFocusToParentOfFocusedWindow() OVERRIDE {
604 ActivateWindowById(1);
605 EXPECT_EQ(1, GetFocusedWindowId());
607 EXPECT_EQ(11, GetFocusedWindowId());
609 // Focus should _not_ shift to the parent of the already-focused window.
610 EXPECT_EQ(11, GetFocusedWindowId());
612 virtual void FocusRulesOverride() OVERRIDE {
613 EXPECT_EQ(NULL, GetFocusedWindow());
615 EXPECT_EQ(11, GetFocusedWindowId());
617 test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
619 // Input events leave focus unchanged; direct API calls will change focus
620 // to the restricted window.
621 int focused_window = IsInputEvent() ? 11 : 211;
622 EXPECT_EQ(focused_window, GetFocusedWindowId());
624 test_focus_rules()->set_focus_restriction(NULL);
626 EXPECT_EQ(12, GetFocusedWindowId());
628 virtual void ActivationRulesOverride() OVERRIDE {
629 ActivateWindowById(1);
630 EXPECT_EQ(1, GetActiveWindowId());
631 EXPECT_EQ(1, GetFocusedWindowId());
633 aura::Window* w3 = root_window()->GetChildById(3);
634 test_focus_rules()->set_focus_restriction(w3);
636 ActivateWindowById(2);
637 // Input events leave activation unchanged; direct API calls will activate
638 // the restricted window.
639 int active_window = IsInputEvent() ? 1 : 3;
640 EXPECT_EQ(active_window, GetActiveWindowId());
641 EXPECT_EQ(active_window, GetFocusedWindowId());
643 test_focus_rules()->set_focus_restriction(NULL);
644 ActivateWindowById(2);
645 EXPECT_EQ(2, GetActiveWindowId());
646 EXPECT_EQ(2, GetFocusedWindowId());
648 virtual void ShiftFocusOnActivation() OVERRIDE {
649 // When a window is activated, by default that window is also focused.
650 // An ActivationChangeObserver may shift focus to another window within the
651 // same activatable window.
652 ActivateWindowById(2);
653 EXPECT_EQ(2, GetFocusedWindowId());
654 ActivateWindowById(1);
655 EXPECT_EQ(1, GetFocusedWindowId());
657 ActivateWindowById(2);
659 aura::Window* target = root_window()->GetChildById(1);
660 aura::client::ActivationClient* client =
661 aura::client::GetActivationClient(root_window());
663 scoped_ptr<FocusShiftingActivationObserver> observer(
664 new FocusShiftingActivationObserver(target));
665 observer->set_shift_focus_to(target->GetChildById(11));
666 client->AddObserver(observer.get());
668 ActivateWindowById(1);
670 // w1's ActivationChangeObserver shifted focus to this child, pre-empting
671 // FocusController's default setting.
672 EXPECT_EQ(11, GetFocusedWindowId());
674 ActivateWindowById(2);
675 EXPECT_EQ(2, GetFocusedWindowId());
677 // Simulate a focus reset by the ActivationChangeObserver. This should
678 // trigger the default setting in FocusController.
679 observer->set_shift_focus_to(NULL);
680 ActivateWindowById(1);
681 EXPECT_EQ(1, GetFocusedWindowId());
683 client->RemoveObserver(observer.get());
685 ActivateWindowById(2);
686 EXPECT_EQ(2, GetFocusedWindowId());
687 ActivateWindowById(1);
688 EXPECT_EQ(1, GetFocusedWindowId());
690 virtual void ShiftFocusOnActivationDueToHide() OVERRIDE {
691 // Similar to ShiftFocusOnActivation except the activation change is
692 // triggered by hiding the active window.
693 ActivateWindowById(1);
694 EXPECT_EQ(1, GetFocusedWindowId());
696 // Removes window 3 as candidate for next activatable window.
697 root_window()->GetChildById(3)->Hide();
698 EXPECT_EQ(1, GetFocusedWindowId());
700 aura::Window* target = root_window()->GetChildById(2);
701 aura::client::ActivationClient* client =
702 aura::client::GetActivationClient(root_window());
704 scoped_ptr<FocusShiftingActivationObserver> observer(
705 new FocusShiftingActivationObserver(target));
706 observer->set_shift_focus_to(target->GetChildById(21));
707 client->AddObserver(observer.get());
709 // Hide the active window.
710 root_window()->GetChildById(1)->Hide();
712 EXPECT_EQ(21, GetFocusedWindowId());
714 client->RemoveObserver(observer.get());
716 virtual void NoShiftActiveOnActivation() OVERRIDE {
717 // When a window is activated, we need to prevent any change to activation
718 // from being made in response to an activation change notification.
721 virtual void NoFocusChangeOnClickOnCaptureWindow() OVERRIDE {
722 scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
723 new aura::client::DefaultCaptureClient(root_window()));
724 // Clicking on a window which has capture should not cause a focus change
725 // to the window. This test verifies whether that is indeed the case.
726 ActivateWindowById(1);
728 EXPECT_EQ(1, GetActiveWindowId());
729 EXPECT_EQ(1, GetFocusedWindowId());
731 aura::Window* w2 = root_window()->GetChildById(2);
732 aura::client::GetCaptureClient(root_window())->SetCapture(w2);
733 aura::test::EventGenerator generator(root_window(), w2);
734 generator.ClickLeftButton();
736 EXPECT_EQ(1, GetActiveWindowId());
737 EXPECT_EQ(1, GetFocusedWindowId());
738 aura::client::GetCaptureClient(root_window())->ReleaseCapture(w2);
741 // Verifies focus change is honored while capture held.
742 virtual void ChangeFocusWhenNothingFocusedAndCaptured() OVERRIDE {
743 scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
744 new aura::client::DefaultCaptureClient(root_window()));
745 aura::Window* w1 = root_window()->GetChildById(1);
746 aura::client::GetCaptureClient(root_window())->SetCapture(w1);
748 EXPECT_EQ(-1, GetActiveWindowId());
749 EXPECT_EQ(-1, GetFocusedWindowId());
753 EXPECT_EQ(1, GetActiveWindowId());
754 EXPECT_EQ(1, GetFocusedWindowId());
756 aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
759 // Verifies if a window that loses activation or focus is deleted during
760 // observer notification we don't pass the deleted window to other observers.
761 virtual void DontPassDeletedWindow() OVERRIDE {
764 EXPECT_EQ(1, GetActiveWindowId());
765 EXPECT_EQ(1, GetFocusedWindowId());
768 aura::Window* to_delete = root_window()->GetChildById(1);
769 DeleteOnLoseActivationChangeObserver observer1(to_delete);
770 RecordingActivationAndFocusChangeObserver observer2(root_window(),
775 EXPECT_EQ(2, GetActiveWindowId());
776 EXPECT_EQ(2, GetFocusedWindowId());
778 EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
779 EXPECT_FALSE(observer2.was_notified_with_deleted_window());
783 aura::Window* to_delete = root_window()->GetChildById(2);
784 DeleteOnLoseFocusChangeObserver observer1(to_delete);
785 RecordingActivationAndFocusChangeObserver observer2(root_window(),
790 EXPECT_EQ(3, GetActiveWindowId());
791 EXPECT_EQ(3, GetFocusedWindowId());
793 EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
794 EXPECT_FALSE(observer2.was_notified_with_deleted_window());
799 DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase);
802 // Focus and Activation changes via aura::client::ActivationClient API.
803 class FocusControllerApiTest : public FocusControllerDirectTestBase {
805 FocusControllerApiTest() {}
808 // Overridden from FocusControllerTestBase:
809 virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
812 virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
813 ActivateWindow(window);
815 virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
816 DeactivateWindow(window);
818 virtual bool IsInputEvent() OVERRIDE { return false; }
820 DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest);
823 // Focus and Activation changes via input events.
824 class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
826 FocusControllerMouseEventTest() {}
829 // Overridden from FocusControllerTestBase:
830 virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
831 aura::test::EventGenerator generator(root_window(), window);
832 generator.ClickLeftButton();
834 virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
835 aura::test::EventGenerator generator(root_window(), window);
836 generator.ClickLeftButton();
838 virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
839 aura::Window* next_activatable =
840 test_focus_rules()->GetNextActivatableWindow(window);
841 aura::test::EventGenerator generator(root_window(), next_activatable);
842 generator.ClickLeftButton();
844 virtual bool IsInputEvent() OVERRIDE { return true; }
846 DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest);
849 class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
851 FocusControllerGestureEventTest() {}
854 // Overridden from FocusControllerTestBase:
855 virtual void FocusWindowDirect(aura::Window* window) OVERRIDE {
856 aura::test::EventGenerator generator(root_window(), window);
857 generator.GestureTapAt(window->bounds().CenterPoint());
859 virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
860 aura::test::EventGenerator generator(root_window(), window);
861 generator.GestureTapAt(window->bounds().CenterPoint());
863 virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
864 aura::Window* next_activatable =
865 test_focus_rules()->GetNextActivatableWindow(window);
866 aura::test::EventGenerator generator(root_window(), next_activatable);
867 generator.GestureTapAt(window->bounds().CenterPoint());
869 virtual bool IsInputEvent() OVERRIDE { return true; }
871 DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest);
874 // Test base for tests where focus is implicitly set to a window as the result
875 // of a disposition change to the focused window or the hierarchy that contains
877 class FocusControllerImplicitTestBase : public FocusControllerTestBase {
879 explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {}
881 aura::Window* GetDispositionWindow(aura::Window* window) {
882 return parent_ ? window->parent() : window;
885 // Change the disposition of |window| in such a way as it will lose focus.
886 virtual void ChangeWindowDisposition(aura::Window* window) = 0;
888 // Allow each disposition change test to add additional post-disposition
889 // change expectations.
890 virtual void PostDispostionChangeExpectations() {}
892 // Overridden from FocusControllerTestBase:
893 virtual void BasicFocus() OVERRIDE {
894 EXPECT_EQ(NULL, GetFocusedWindow());
896 aura::Window* w211 = root_window()->GetChildById(211);
898 EXPECT_EQ(211, GetFocusedWindowId());
900 ChangeWindowDisposition(w211);
901 // BasicFocusRules passes focus to the parent.
902 EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId());
904 virtual void BasicActivation() OVERRIDE {
905 DCHECK(!parent_) << "Activation tests don't support parent changes.";
907 EXPECT_EQ(NULL, GetActiveWindow());
909 aura::Window* w2 = root_window()->GetChildById(2);
911 EXPECT_EQ(2, GetActiveWindowId());
913 ChangeWindowDisposition(w2);
914 EXPECT_EQ(3, GetActiveWindowId());
915 PostDispostionChangeExpectations();
917 virtual void FocusEvents() OVERRIDE {
918 aura::Window* w211 = root_window()->GetChildById(211);
921 ScopedFocusNotificationObserver root_observer(root_window());
922 ScopedTargetFocusNotificationObserver observer211(root_window(), 211);
923 root_observer.ExpectCounts(0, 0);
924 observer211.ExpectCounts(0, 0);
926 ChangeWindowDisposition(w211);
927 root_observer.ExpectCounts(0, 1);
928 observer211.ExpectCounts(0, 1);
930 virtual void ActivationEvents() OVERRIDE {
931 DCHECK(!parent_) << "Activation tests don't support parent changes.";
933 aura::Window* w2 = root_window()->GetChildById(2);
936 ScopedFocusNotificationObserver root_observer(root_window());
937 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
938 ScopedTargetFocusNotificationObserver observer3(root_window(), 3);
939 root_observer.ExpectCounts(0, 0);
940 observer2.ExpectCounts(0, 0);
941 observer3.ExpectCounts(0, 0);
943 ChangeWindowDisposition(w2);
944 root_observer.ExpectCounts(1, 1);
945 observer2.ExpectCounts(1, 1);
946 observer3.ExpectCounts(1, 1);
948 virtual void FocusRulesOverride() OVERRIDE {
949 EXPECT_EQ(NULL, GetFocusedWindow());
950 aura::Window* w211 = root_window()->GetChildById(211);
952 EXPECT_EQ(211, GetFocusedWindowId());
954 test_focus_rules()->set_focus_restriction(root_window()->GetChildById(11));
955 ChangeWindowDisposition(w211);
956 // Normally, focus would shift to the parent (w21) but the override shifts
958 EXPECT_EQ(11, GetFocusedWindowId());
960 test_focus_rules()->set_focus_restriction(NULL);
962 virtual void ActivationRulesOverride() OVERRIDE {
963 DCHECK(!parent_) << "Activation tests don't support parent changes.";
965 aura::Window* w1 = root_window()->GetChildById(1);
968 EXPECT_EQ(1, GetActiveWindowId());
969 EXPECT_EQ(1, GetFocusedWindowId());
971 aura::Window* w3 = root_window()->GetChildById(3);
972 test_focus_rules()->set_focus_restriction(w3);
974 // Normally, activation/focus would move to w2, but since we have a focus
975 // restriction, it should move to w3 instead.
976 ChangeWindowDisposition(w1);
977 EXPECT_EQ(3, GetActiveWindowId());
978 EXPECT_EQ(3, GetFocusedWindowId());
980 test_focus_rules()->set_focus_restriction(NULL);
981 ActivateWindow(root_window()->GetChildById(2));
982 EXPECT_EQ(2, GetActiveWindowId());
983 EXPECT_EQ(2, GetFocusedWindowId());
987 // When true, the disposition change occurs to the parent of the window
988 // instead of to the window. This verifies that changes occurring in the
989 // hierarchy that contains the window affect the window's focus.
992 DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase);
995 // Focus and Activation changes in response to window visibility changes.
996 class FocusControllerHideTest : public FocusControllerImplicitTestBase {
998 FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {}
1001 FocusControllerHideTest(bool parent)
1002 : FocusControllerImplicitTestBase(parent) {}
1004 // Overridden from FocusControllerImplicitTestBase:
1005 virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
1006 GetDispositionWindow(window)->Hide();
1010 DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest);
1013 // Focus and Activation changes in response to window parent visibility
1015 class FocusControllerParentHideTest : public FocusControllerHideTest {
1017 FocusControllerParentHideTest() : FocusControllerHideTest(true) {}
1020 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest);
1023 // Focus and Activation changes in response to window destruction.
1024 class FocusControllerDestructionTest : public FocusControllerImplicitTestBase {
1026 FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {}
1029 FocusControllerDestructionTest(bool parent)
1030 : FocusControllerImplicitTestBase(parent) {}
1032 // Overridden from FocusControllerImplicitTestBase:
1033 virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
1034 delete GetDispositionWindow(window);
1038 DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest);
1041 // Focus and Activation changes in response to window parent destruction.
1042 class FocusControllerParentDestructionTest
1043 : public FocusControllerDestructionTest {
1045 FocusControllerParentDestructionTest()
1046 : FocusControllerDestructionTest(true) {}
1049 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentDestructionTest);
1052 // Focus and Activation changes in response to window removal.
1053 class FocusControllerRemovalTest : public FocusControllerImplicitTestBase {
1055 FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {}
1058 FocusControllerRemovalTest(bool parent)
1059 : FocusControllerImplicitTestBase(parent) {}
1061 // Overridden from FocusControllerImplicitTestBase:
1062 virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE {
1063 aura::Window* disposition_window = GetDispositionWindow(window);
1064 disposition_window->parent()->RemoveChild(disposition_window);
1065 window_owner_.reset(disposition_window);
1067 virtual void TearDown() OVERRIDE {
1068 window_owner_.reset();
1069 FocusControllerImplicitTestBase::TearDown();
1073 scoped_ptr<aura::Window> window_owner_;
1075 DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest);
1078 // Focus and Activation changes in response to window parent removal.
1079 class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
1081 FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {}
1084 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest);
1088 #define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
1089 TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }
1091 // Runs direct focus change tests (input events and API calls).
1092 #define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
1093 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \
1094 FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \
1095 FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME)
1097 // Runs implicit focus change tests for disposition changes to target.
1098 #define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
1099 FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \
1100 FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
1101 FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME)
1103 // Runs implicit focus change tests for disposition changes to target's parent
1105 #define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \
1106 /* TODO(beng): parent destruction tests are not supported at
1107 present due to workspace manager issues. \
1108 FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \
1109 FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \
1110 FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)
1112 // Runs all implicit focus change tests (changes to the target and target's
1113 // parent hierarchy)
1114 #define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \
1115 IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
1116 IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)
1118 // Runs all possible focus change tests.
1119 #define ALL_FOCUS_TESTS(TESTNAME) \
1120 DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
1121 IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)
1123 // Runs focus change tests that apply only to the target. For example,
1124 // implicit activation changes caused by window disposition changes do not
1125 // occur when changes to the containing hierarchy happen.
1126 #define TARGET_FOCUS_TESTS(TESTNAME) \
1127 DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
1128 IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)
1130 // - Focuses a window, verifies that focus changed.
1131 ALL_FOCUS_TESTS(BasicFocus);
1133 // - Activates a window, verifies that activation changed.
1134 TARGET_FOCUS_TESTS(BasicActivation);
1136 // - Focuses a window, verifies that focus events were dispatched.
1137 ALL_FOCUS_TESTS(FocusEvents);
1139 // - Focuses or activates a window multiple times, verifies that events are only
1140 // dispatched when focus/activation actually changes.
1141 DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents);
1142 DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents);
1144 // - Activates a window, verifies that activation events were dispatched.
1145 TARGET_FOCUS_TESTS(ActivationEvents);
1147 // - Attempts to active a hidden window, verifies that current window is
1148 // attempted to be reactivated and the appropriate event dispatched.
1149 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents);
1151 // - Input events/API calls shift focus between focusable windows within the
1153 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow);
1155 // - Input events/API calls to a child window of an inactive window shifts
1156 // activation to the activatable parent and focuses the child.
1157 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow);
1159 // - Input events/API calls to focus the parent of the focused window do not
1160 // shift focus away from the child.
1161 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow);
1163 // - Verifies that FocusRules determine what can be focused.
1164 ALL_FOCUS_TESTS(FocusRulesOverride);
1166 // - Verifies that FocusRules determine what can be activated.
1167 TARGET_FOCUS_TESTS(ActivationRulesOverride);
1169 // - Verifies that attempts to change focus or activation from a focus or
1170 // activation change observer are ignored.
1171 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation);
1172 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide);
1173 DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation);
1175 // Clicking on a window which has capture should not result in a focus change.
1176 DIRECT_FOCUS_CHANGE_TESTS(NoFocusChangeOnClickOnCaptureWindow);
1178 FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
1179 ChangeFocusWhenNothingFocusedAndCaptured);
1181 // See description above DontPassDeletedWindow() for details.
1182 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow);