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/test_window_delegate.h"
14 #include "ui/aura/test/test_windows.h"
15 #include "ui/aura/window.h"
16 #include "ui/aura/window_event_dispatcher.h"
17 #include "ui/aura/window_tracker.h"
18 #include "ui/base/ime/dummy_text_input_client.h"
19 #include "ui/base/ime/text_input_focus_manager.h"
20 #include "ui/events/event.h"
21 #include "ui/events/event_constants.h"
22 #include "ui/events/event_handler.h"
23 #include "ui/events/test/event_generator.h"
24 #include "ui/wm/core/base_focus_rules.h"
25 #include "ui/wm/core/wm_state.h"
26 #include "ui/wm/public/activation_change_observer.h"
27 #include "ui/wm/public/activation_client.h"
31 class FocusNotificationObserver : public aura::client::ActivationChangeObserver,
32 public aura::client::FocusChangeObserver {
34 FocusNotificationObserver()
35 : activation_changed_count_(0),
36 focus_changed_count_(0),
37 reactivation_count_(0),
38 reactivation_requested_window_(NULL),
39 reactivation_actual_window_(NULL) {}
40 ~FocusNotificationObserver() override {}
42 void ExpectCounts(int activation_changed_count, int focus_changed_count) {
43 EXPECT_EQ(activation_changed_count, activation_changed_count_);
44 EXPECT_EQ(focus_changed_count, focus_changed_count_);
46 int reactivation_count() const {
47 return reactivation_count_;
49 aura::Window* reactivation_requested_window() const {
50 return reactivation_requested_window_;
52 aura::Window* reactivation_actual_window() const {
53 return reactivation_actual_window_;
57 // Overridden from aura::client::ActivationChangeObserver:
58 void OnWindowActivated(aura::Window* gained_active,
59 aura::Window* lost_active) override {
60 ++activation_changed_count_;
62 void OnAttemptToReactivateWindow(aura::Window* request_active,
63 aura::Window* actual_active) override {
64 ++reactivation_count_;
65 reactivation_requested_window_ = request_active;
66 reactivation_actual_window_ = actual_active;
69 // Overridden from aura::client::FocusChangeObserver:
70 void OnWindowFocused(aura::Window* gained_focus,
71 aura::Window* lost_focus) override {
72 ++focus_changed_count_;
75 int activation_changed_count_;
76 int focus_changed_count_;
77 int reactivation_count_;
78 aura::Window* reactivation_requested_window_;
79 aura::Window* reactivation_actual_window_;
81 DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver);
86 virtual aura::Window* GetDeletedWindow() = 0;
89 virtual ~WindowDeleter() {}
92 // ActivationChangeObserver and FocusChangeObserver that keeps track of whether
93 // it was notified about activation changes or focus changes with a deleted
95 class RecordingActivationAndFocusChangeObserver
96 : public aura::client::ActivationChangeObserver,
97 public aura::client::FocusChangeObserver {
99 RecordingActivationAndFocusChangeObserver(aura::Window* root,
100 WindowDeleter* deleter)
103 was_notified_with_deleted_window_(false) {
104 aura::client::GetActivationClient(root_)->AddObserver(this);
105 aura::client::GetFocusClient(root_)->AddObserver(this);
107 ~RecordingActivationAndFocusChangeObserver() override {
108 aura::client::GetActivationClient(root_)->RemoveObserver(this);
109 aura::client::GetFocusClient(root_)->RemoveObserver(this);
112 bool was_notified_with_deleted_window() const {
113 return was_notified_with_deleted_window_;
116 // Overridden from aura::client::ActivationChangeObserver:
117 void OnWindowActivated(aura::Window* gained_active,
118 aura::Window* lost_active) override {
119 if (lost_active && lost_active == deleter_->GetDeletedWindow())
120 was_notified_with_deleted_window_ = true;
123 // Overridden from aura::client::FocusChangeObserver:
124 void OnWindowFocused(aura::Window* gained_focus,
125 aura::Window* lost_focus) override {
126 if (lost_focus && lost_focus == deleter_->GetDeletedWindow())
127 was_notified_with_deleted_window_ = true;
134 WindowDeleter* deleter_;
136 // Whether the observer was notified about the loss of activation or the
137 // loss of focus with a window already deleted by |deleter_| as the
138 // |lost_active| or |lost_focus| parameter.
139 bool was_notified_with_deleted_window_;
141 DISALLOW_COPY_AND_ASSIGN(RecordingActivationAndFocusChangeObserver);
144 // ActivationChangeObserver that deletes the window losing activation.
145 class DeleteOnLoseActivationChangeObserver :
146 public aura::client::ActivationChangeObserver,
147 public WindowDeleter {
149 explicit DeleteOnLoseActivationChangeObserver(aura::Window* window)
150 : root_(window->GetRootWindow()),
153 aura::client::GetActivationClient(root_)->AddObserver(this);
155 ~DeleteOnLoseActivationChangeObserver() override {
156 aura::client::GetActivationClient(root_)->RemoveObserver(this);
159 // Overridden from aura::client::ActivationChangeObserver:
160 void OnWindowActivated(aura::Window* gained_active,
161 aura::Window* lost_active) override {
162 if (window_ && lost_active == window_) {
168 // Overridden from WindowDeleter:
169 aura::Window* GetDeletedWindow() override {
170 return did_delete_ ? window_ : NULL;
175 aura::Window* window_;
178 DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseActivationChangeObserver);
181 // FocusChangeObserver that deletes the window losing focus.
182 class DeleteOnLoseFocusChangeObserver
183 : public aura::client::FocusChangeObserver,
184 public WindowDeleter {
186 explicit DeleteOnLoseFocusChangeObserver(aura::Window* window)
187 : root_(window->GetRootWindow()),
190 aura::client::GetFocusClient(root_)->AddObserver(this);
192 ~DeleteOnLoseFocusChangeObserver() override {
193 aura::client::GetFocusClient(root_)->RemoveObserver(this);
196 // Overridden from aura::client::FocusChangeObserver:
197 void OnWindowFocused(aura::Window* gained_focus,
198 aura::Window* lost_focus) override {
199 if (window_ && lost_focus == window_) {
205 // Overridden from WindowDeleter:
206 aura::Window* GetDeletedWindow() override {
207 return did_delete_ ? window_ : NULL;
212 aura::Window* window_;
215 DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseFocusChangeObserver);
218 class ScopedFocusNotificationObserver : public FocusNotificationObserver {
220 ScopedFocusNotificationObserver(aura::Window* root_window)
221 : root_window_(root_window) {
222 aura::client::GetActivationClient(root_window_)->AddObserver(this);
223 aura::client::GetFocusClient(root_window_)->AddObserver(this);
225 ~ScopedFocusNotificationObserver() override {
226 aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
227 aura::client::GetFocusClient(root_window_)->RemoveObserver(this);
231 aura::Window* root_window_;
233 DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver);
236 class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver {
238 ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id)
239 : target_(root_window->GetChildById(id)) {
240 aura::client::SetActivationChangeObserver(target_, this);
241 aura::client::SetFocusChangeObserver(target_, this);
242 tracker_.Add(target_);
244 ~ScopedTargetFocusNotificationObserver() override {
245 if (tracker_.Contains(target_)) {
246 aura::client::SetActivationChangeObserver(target_, NULL);
247 aura::client::SetFocusChangeObserver(target_, NULL);
252 aura::Window* target_;
253 aura::WindowTracker tracker_;
255 DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver);
258 class ScopedFocusedTextInputClientChanger
259 : public ScopedFocusNotificationObserver {
261 ScopedFocusedTextInputClientChanger(aura::Window* root_window,
262 ui::TextInputClient* text_input_client)
263 : ScopedFocusNotificationObserver(root_window),
264 text_input_client_(text_input_client) {}
267 // Overridden from aura::client::FocusChangeObserver:
268 void OnWindowFocused(aura::Window* gained_focus,
269 aura::Window* lost_focus) override {
270 ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(
274 ui::TextInputClient* text_input_client_;
277 // Used to fake the handling of events in the pre-target phase.
278 class SimpleEventHandler : public ui::EventHandler {
280 SimpleEventHandler() {}
281 ~SimpleEventHandler() override {}
283 // Overridden from ui::EventHandler:
284 void OnMouseEvent(ui::MouseEvent* event) override { event->SetHandled(); }
285 void OnGestureEvent(ui::GestureEvent* event) override { event->SetHandled(); }
288 DISALLOW_COPY_AND_ASSIGN(SimpleEventHandler);
291 class FocusShiftingActivationObserver
292 : public aura::client::ActivationChangeObserver {
294 explicit FocusShiftingActivationObserver(aura::Window* activated_window)
295 : activated_window_(activated_window),
296 shift_focus_to_(NULL) {}
297 ~FocusShiftingActivationObserver() override {}
299 void set_shift_focus_to(aura::Window* shift_focus_to) {
300 shift_focus_to_ = shift_focus_to;
304 // Overridden from aura::client::ActivationChangeObserver:
305 void OnWindowActivated(aura::Window* gained_active,
306 aura::Window* lost_active) override {
307 // Shift focus to a child. This should prevent the default focusing from
308 // occurring in FocusController::FocusWindow().
309 if (gained_active == activated_window_) {
310 aura::client::FocusClient* client =
311 aura::client::GetFocusClient(gained_active);
312 client->FocusWindow(shift_focus_to_);
316 aura::Window* activated_window_;
317 aura::Window* shift_focus_to_;
319 DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver);
322 // BaseFocusRules subclass that allows basic overrides of focus/activation to
323 // be tested. This is intended more as a test that the override system works at
324 // all, rather than as an exhaustive set of use cases, those should be covered
325 // in tests for those FocusRules implementations.
326 class TestFocusRules : public BaseFocusRules {
328 TestFocusRules() : focus_restriction_(NULL) {}
330 // Restricts focus and activation to this window and its child hierarchy.
331 void set_focus_restriction(aura::Window* focus_restriction) {
332 focus_restriction_ = focus_restriction;
335 // Overridden from BaseFocusRules:
336 bool SupportsChildActivation(aura::Window* window) const override {
337 // In FocusControllerTests, only the RootWindow has activatable children.
338 return window->GetRootWindow() == window;
340 bool CanActivateWindow(aura::Window* window) const override {
341 // Restricting focus to a non-activatable child window means the activatable
342 // parent outside the focus restriction is activatable.
344 CanFocusOrActivate(window) || window->Contains(focus_restriction_);
345 return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
347 bool CanFocusWindow(aura::Window* window) const override {
348 return CanFocusOrActivate(window) ?
349 BaseFocusRules::CanFocusWindow(window) : false;
351 aura::Window* GetActivatableWindow(aura::Window* window) const override {
352 return BaseFocusRules::GetActivatableWindow(
353 CanFocusOrActivate(window) ? window : focus_restriction_);
355 aura::Window* GetFocusableWindow(aura::Window* window) const override {
356 return BaseFocusRules::GetFocusableWindow(
357 CanFocusOrActivate(window) ? window : focus_restriction_);
359 aura::Window* GetNextActivatableWindow(aura::Window* ignore) const override {
360 aura::Window* next_activatable =
361 BaseFocusRules::GetNextActivatableWindow(ignore);
362 return CanFocusOrActivate(next_activatable) ?
363 next_activatable : GetActivatableWindow(focus_restriction_);
367 bool CanFocusOrActivate(aura::Window* window) const {
368 return !focus_restriction_ || focus_restriction_->Contains(window);
371 aura::Window* focus_restriction_;
373 DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
376 // Common infrastructure shared by all FocusController test types.
377 class FocusControllerTestBase : public aura::test::AuraTestBase {
379 FocusControllerTestBase() {}
381 // Overridden from aura::test::AuraTestBase:
382 void SetUp() override {
383 wm_state_.reset(new wm::WMState);
384 // FocusController registers itself as an Env observer so it can catch all
385 // window initializations, including the root_window()'s, so we create it
386 // before allowing the base setup.
387 test_focus_rules_ = new TestFocusRules;
388 focus_controller_.reset(new FocusController(test_focus_rules_));
389 aura::test::AuraTestBase::SetUp();
390 root_window()->AddPreTargetHandler(focus_controller_.get());
391 aura::client::SetFocusClient(root_window(), focus_controller_.get());
392 aura::client::SetActivationClient(root_window(), focus_controller_.get());
394 // Hierarchy used by all tests:
403 aura::Window* w1 = aura::test::CreateTestWindowWithDelegate(
404 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1,
405 gfx::Rect(0, 0, 50, 50), root_window());
406 aura::test::CreateTestWindowWithDelegate(
407 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 11,
408 gfx::Rect(5, 5, 10, 10), w1);
409 aura::test::CreateTestWindowWithDelegate(
410 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 12,
411 gfx::Rect(15, 15, 10, 10), w1);
412 aura::Window* w2 = aura::test::CreateTestWindowWithDelegate(
413 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 2,
414 gfx::Rect(75, 75, 50, 50), root_window());
415 aura::Window* w21 = aura::test::CreateTestWindowWithDelegate(
416 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 21,
417 gfx::Rect(5, 5, 10, 10), w2);
418 aura::test::CreateTestWindowWithDelegate(
419 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 211,
420 gfx::Rect(1, 1, 5, 5), w21);
421 aura::test::CreateTestWindowWithDelegate(
422 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 3,
423 gfx::Rect(125, 125, 50, 50), root_window());
425 void TearDown() override {
426 root_window()->RemovePreTargetHandler(focus_controller_.get());
427 aura::test::AuraTestBase::TearDown();
428 test_focus_rules_ = NULL; // Owned by FocusController.
429 focus_controller_.reset();
433 void FocusWindow(aura::Window* window) {
434 aura::client::GetFocusClient(root_window())->FocusWindow(window);
436 aura::Window* GetFocusedWindow() {
437 return aura::client::GetFocusClient(root_window())->GetFocusedWindow();
439 int GetFocusedWindowId() {
440 aura::Window* focused_window = GetFocusedWindow();
441 return focused_window ? focused_window->id() : -1;
443 void ActivateWindow(aura::Window* window) {
444 aura::client::GetActivationClient(root_window())->ActivateWindow(window);
446 void DeactivateWindow(aura::Window* window) {
447 aura::client::GetActivationClient(root_window())->DeactivateWindow(window);
449 aura::Window* GetActiveWindow() {
450 return aura::client::GetActivationClient(root_window())->GetActiveWindow();
452 int GetActiveWindowId() {
453 aura::Window* active_window = GetActiveWindow();
454 return active_window ? active_window->id() : -1;
457 TestFocusRules* test_focus_rules() { return test_focus_rules_; }
460 virtual void BasicFocus() = 0;
461 virtual void BasicActivation() = 0;
462 virtual void FocusEvents() = 0;
463 virtual void DuplicateFocusEvents() {}
464 virtual void ActivationEvents() = 0;
465 virtual void ReactivationEvents() {}
466 virtual void DuplicateActivationEvents() {}
467 virtual void ShiftFocusWithinActiveWindow() {}
468 virtual void ShiftFocusToChildOfInactiveWindow() {}
469 virtual void ShiftFocusToParentOfFocusedWindow() {}
470 virtual void FocusRulesOverride() = 0;
471 virtual void ActivationRulesOverride() = 0;
472 virtual void ShiftFocusOnActivation() {}
473 virtual void ShiftFocusOnActivationDueToHide() {}
474 virtual void NoShiftActiveOnActivation() {}
475 virtual void NoFocusChangeOnClickOnCaptureWindow() {}
476 virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
477 virtual void DontPassDeletedWindow() {}
478 virtual void FocusedTextInputClient() {}
481 scoped_ptr<FocusController> focus_controller_;
482 TestFocusRules* test_focus_rules_;
483 scoped_ptr<wm::WMState> wm_state_;
485 DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase);
488 // Test base for tests where focus is directly set to a target window.
489 class FocusControllerDirectTestBase : public FocusControllerTestBase {
491 FocusControllerDirectTestBase() {}
493 // Different test types shift focus in different ways.
494 virtual void FocusWindowDirect(aura::Window* window) = 0;
495 virtual void ActivateWindowDirect(aura::Window* window) = 0;
496 virtual void DeactivateWindowDirect(aura::Window* window) = 0;
498 // Input events do not change focus if the window can not be focused.
499 virtual bool IsInputEvent() = 0;
501 void FocusWindowById(int id) {
502 aura::Window* window = root_window()->GetChildById(id);
504 FocusWindowDirect(window);
506 void ActivateWindowById(int id) {
507 aura::Window* window = root_window()->GetChildById(id);
509 ActivateWindowDirect(window);
512 // Overridden from FocusControllerTestBase:
513 void BasicFocus() override {
514 EXPECT_EQ(NULL, GetFocusedWindow());
516 EXPECT_EQ(1, GetFocusedWindowId());
518 EXPECT_EQ(2, GetFocusedWindowId());
520 void BasicActivation() override {
521 EXPECT_EQ(NULL, GetActiveWindow());
522 ActivateWindowById(1);
523 EXPECT_EQ(1, GetActiveWindowId());
524 ActivateWindowById(2);
525 EXPECT_EQ(2, GetActiveWindowId());
526 // Verify that attempting to deactivate NULL does not crash and does not
527 // change activation.
528 DeactivateWindow(NULL);
529 EXPECT_EQ(2, GetActiveWindowId());
530 DeactivateWindow(GetActiveWindow());
531 EXPECT_EQ(1, GetActiveWindowId());
533 void FocusEvents() override {
534 ScopedFocusNotificationObserver root_observer(root_window());
535 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
536 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
538 root_observer.ExpectCounts(0, 0);
539 observer1.ExpectCounts(0, 0);
540 observer2.ExpectCounts(0, 0);
543 root_observer.ExpectCounts(1, 1);
544 observer1.ExpectCounts(1, 1);
545 observer2.ExpectCounts(0, 0);
548 root_observer.ExpectCounts(2, 2);
549 observer1.ExpectCounts(2, 2);
550 observer2.ExpectCounts(1, 1);
552 void DuplicateFocusEvents() override {
553 // Focusing an existing focused window should not resend focus events.
554 ScopedFocusNotificationObserver root_observer(root_window());
555 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
557 root_observer.ExpectCounts(0, 0);
558 observer1.ExpectCounts(0, 0);
561 root_observer.ExpectCounts(1, 1);
562 observer1.ExpectCounts(1, 1);
565 root_observer.ExpectCounts(1, 1);
566 observer1.ExpectCounts(1, 1);
568 void ActivationEvents() override {
569 ActivateWindowById(1);
571 ScopedFocusNotificationObserver root_observer(root_window());
572 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
573 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
575 root_observer.ExpectCounts(0, 0);
576 observer1.ExpectCounts(0, 0);
577 observer2.ExpectCounts(0, 0);
579 ActivateWindowById(2);
580 root_observer.ExpectCounts(1, 1);
581 observer1.ExpectCounts(1, 1);
582 observer2.ExpectCounts(1, 1);
584 void ReactivationEvents() override {
585 ActivateWindowById(1);
586 ScopedFocusNotificationObserver root_observer(root_window());
587 EXPECT_EQ(0, root_observer.reactivation_count());
588 root_window()->GetChildById(2)->Hide();
589 // When we attempt to activate "2", which cannot be activated because it
590 // is not visible, "1" will be reactivated.
591 ActivateWindowById(2);
592 EXPECT_EQ(1, root_observer.reactivation_count());
593 EXPECT_EQ(root_window()->GetChildById(2),
594 root_observer.reactivation_requested_window());
595 EXPECT_EQ(root_window()->GetChildById(1),
596 root_observer.reactivation_actual_window());
598 void DuplicateActivationEvents() override {
599 // Activating an existing active window should not resend activation events.
600 ActivateWindowById(1);
602 ScopedFocusNotificationObserver root_observer(root_window());
603 ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
604 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
606 root_observer.ExpectCounts(0, 0);
607 observer1.ExpectCounts(0, 0);
608 observer2.ExpectCounts(0, 0);
610 ActivateWindowById(2);
611 root_observer.ExpectCounts(1, 1);
612 observer1.ExpectCounts(1, 1);
613 observer2.ExpectCounts(1, 1);
615 ActivateWindowById(2);
616 root_observer.ExpectCounts(1, 1);
617 observer1.ExpectCounts(1, 1);
618 observer2.ExpectCounts(1, 1);
620 void ShiftFocusWithinActiveWindow() override {
621 ActivateWindowById(1);
622 EXPECT_EQ(1, GetActiveWindowId());
623 EXPECT_EQ(1, GetFocusedWindowId());
625 EXPECT_EQ(11, GetFocusedWindowId());
627 EXPECT_EQ(12, GetFocusedWindowId());
629 void ShiftFocusToChildOfInactiveWindow() override {
630 ActivateWindowById(2);
631 EXPECT_EQ(2, GetActiveWindowId());
632 EXPECT_EQ(2, GetFocusedWindowId());
634 EXPECT_EQ(1, GetActiveWindowId());
635 EXPECT_EQ(11, GetFocusedWindowId());
637 void ShiftFocusToParentOfFocusedWindow() override {
638 ActivateWindowById(1);
639 EXPECT_EQ(1, GetFocusedWindowId());
641 EXPECT_EQ(11, GetFocusedWindowId());
643 // Focus should _not_ shift to the parent of the already-focused window.
644 EXPECT_EQ(11, GetFocusedWindowId());
646 void FocusRulesOverride() override {
647 EXPECT_EQ(NULL, GetFocusedWindow());
649 EXPECT_EQ(11, GetFocusedWindowId());
651 test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
653 // Input events leave focus unchanged; direct API calls will change focus
654 // to the restricted window.
655 int focused_window = IsInputEvent() ? 11 : 211;
656 EXPECT_EQ(focused_window, GetFocusedWindowId());
658 test_focus_rules()->set_focus_restriction(NULL);
660 EXPECT_EQ(12, GetFocusedWindowId());
662 void ActivationRulesOverride() override {
663 ActivateWindowById(1);
664 EXPECT_EQ(1, GetActiveWindowId());
665 EXPECT_EQ(1, GetFocusedWindowId());
667 aura::Window* w3 = root_window()->GetChildById(3);
668 test_focus_rules()->set_focus_restriction(w3);
670 ActivateWindowById(2);
671 // Input events leave activation unchanged; direct API calls will activate
672 // the restricted window.
673 int active_window = IsInputEvent() ? 1 : 3;
674 EXPECT_EQ(active_window, GetActiveWindowId());
675 EXPECT_EQ(active_window, GetFocusedWindowId());
677 test_focus_rules()->set_focus_restriction(NULL);
678 ActivateWindowById(2);
679 EXPECT_EQ(2, GetActiveWindowId());
680 EXPECT_EQ(2, GetFocusedWindowId());
682 void ShiftFocusOnActivation() override {
683 // When a window is activated, by default that window is also focused.
684 // An ActivationChangeObserver may shift focus to another window within the
685 // same activatable window.
686 ActivateWindowById(2);
687 EXPECT_EQ(2, GetFocusedWindowId());
688 ActivateWindowById(1);
689 EXPECT_EQ(1, GetFocusedWindowId());
691 ActivateWindowById(2);
693 aura::Window* target = root_window()->GetChildById(1);
694 aura::client::ActivationClient* client =
695 aura::client::GetActivationClient(root_window());
697 scoped_ptr<FocusShiftingActivationObserver> observer(
698 new FocusShiftingActivationObserver(target));
699 observer->set_shift_focus_to(target->GetChildById(11));
700 client->AddObserver(observer.get());
702 ActivateWindowById(1);
704 // w1's ActivationChangeObserver shifted focus to this child, pre-empting
705 // FocusController's default setting.
706 EXPECT_EQ(11, GetFocusedWindowId());
708 ActivateWindowById(2);
709 EXPECT_EQ(2, GetFocusedWindowId());
711 // Simulate a focus reset by the ActivationChangeObserver. This should
712 // trigger the default setting in FocusController.
713 observer->set_shift_focus_to(NULL);
714 ActivateWindowById(1);
715 EXPECT_EQ(1, GetFocusedWindowId());
717 client->RemoveObserver(observer.get());
719 ActivateWindowById(2);
720 EXPECT_EQ(2, GetFocusedWindowId());
721 ActivateWindowById(1);
722 EXPECT_EQ(1, GetFocusedWindowId());
724 void ShiftFocusOnActivationDueToHide() override {
725 // Similar to ShiftFocusOnActivation except the activation change is
726 // triggered by hiding the active window.
727 ActivateWindowById(1);
728 EXPECT_EQ(1, GetFocusedWindowId());
730 // Removes window 3 as candidate for next activatable window.
731 root_window()->GetChildById(3)->Hide();
732 EXPECT_EQ(1, GetFocusedWindowId());
734 aura::Window* target = root_window()->GetChildById(2);
735 aura::client::ActivationClient* client =
736 aura::client::GetActivationClient(root_window());
738 scoped_ptr<FocusShiftingActivationObserver> observer(
739 new FocusShiftingActivationObserver(target));
740 observer->set_shift_focus_to(target->GetChildById(21));
741 client->AddObserver(observer.get());
743 // Hide the active window.
744 root_window()->GetChildById(1)->Hide();
746 EXPECT_EQ(21, GetFocusedWindowId());
748 client->RemoveObserver(observer.get());
750 void NoShiftActiveOnActivation() override {
751 // When a window is activated, we need to prevent any change to activation
752 // from being made in response to an activation change notification.
755 void NoFocusChangeOnClickOnCaptureWindow() override {
756 scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
757 new aura::client::DefaultCaptureClient(root_window()));
758 // Clicking on a window which has capture should not cause a focus change
759 // to the window. This test verifies whether that is indeed the case.
760 ActivateWindowById(1);
762 EXPECT_EQ(1, GetActiveWindowId());
763 EXPECT_EQ(1, GetFocusedWindowId());
765 aura::Window* w2 = root_window()->GetChildById(2);
766 aura::client::GetCaptureClient(root_window())->SetCapture(w2);
767 ui::test::EventGenerator generator(root_window(), w2);
768 generator.ClickLeftButton();
770 EXPECT_EQ(1, GetActiveWindowId());
771 EXPECT_EQ(1, GetFocusedWindowId());
772 aura::client::GetCaptureClient(root_window())->ReleaseCapture(w2);
775 // Verifies focus change is honored while capture held.
776 void ChangeFocusWhenNothingFocusedAndCaptured() override {
777 scoped_ptr<aura::client::DefaultCaptureClient> capture_client(
778 new aura::client::DefaultCaptureClient(root_window()));
779 aura::Window* w1 = root_window()->GetChildById(1);
780 aura::client::GetCaptureClient(root_window())->SetCapture(w1);
782 EXPECT_EQ(-1, GetActiveWindowId());
783 EXPECT_EQ(-1, GetFocusedWindowId());
787 EXPECT_EQ(1, GetActiveWindowId());
788 EXPECT_EQ(1, GetFocusedWindowId());
790 aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
793 // Verifies if a window that loses activation or focus is deleted during
794 // observer notification we don't pass the deleted window to other observers.
795 void DontPassDeletedWindow() override {
798 EXPECT_EQ(1, GetActiveWindowId());
799 EXPECT_EQ(1, GetFocusedWindowId());
802 aura::Window* to_delete = root_window()->GetChildById(1);
803 DeleteOnLoseActivationChangeObserver observer1(to_delete);
804 RecordingActivationAndFocusChangeObserver observer2(root_window(),
809 EXPECT_EQ(2, GetActiveWindowId());
810 EXPECT_EQ(2, GetFocusedWindowId());
812 EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
813 EXPECT_FALSE(observer2.was_notified_with_deleted_window());
817 aura::Window* to_delete = root_window()->GetChildById(2);
818 DeleteOnLoseFocusChangeObserver observer1(to_delete);
819 RecordingActivationAndFocusChangeObserver observer2(root_window(),
824 EXPECT_EQ(3, GetActiveWindowId());
825 EXPECT_EQ(3, GetFocusedWindowId());
827 EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
828 EXPECT_FALSE(observer2.was_notified_with_deleted_window());
832 // Verifies if the focused text input client is cleared when a window gains
833 // or loses the focus.
834 void FocusedTextInputClient() override {
835 ui::TextInputFocusManager* text_input_focus_manager =
836 ui::TextInputFocusManager::GetInstance();
837 ui::DummyTextInputClient text_input_client;
838 ui::TextInputClient* null_text_input_client = NULL;
840 EXPECT_EQ(null_text_input_client,
841 text_input_focus_manager->GetFocusedTextInputClient());
843 text_input_focus_manager->FocusTextInputClient(&text_input_client);
844 EXPECT_EQ(&text_input_client,
845 text_input_focus_manager->GetFocusedTextInputClient());
847 // The focused text input client gets cleared when a window gets focused
848 // unless any of observers sets the focused text input client.
849 EXPECT_EQ(null_text_input_client,
850 text_input_focus_manager->GetFocusedTextInputClient());
852 ScopedFocusedTextInputClientChanger text_input_focus_changer(
853 root_window(), &text_input_client);
854 EXPECT_EQ(null_text_input_client,
855 text_input_focus_manager->GetFocusedTextInputClient());
857 // |text_input_focus_changer| sets the focused text input client.
858 EXPECT_EQ(&text_input_client,
859 text_input_focus_manager->GetFocusedTextInputClient());
862 // The focused text input client gets cleared when a window loses the focus.
863 EXPECT_EQ(null_text_input_client,
864 text_input_focus_manager->GetFocusedTextInputClient());
868 DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase);
871 // Focus and Activation changes via aura::client::ActivationClient API.
872 class FocusControllerApiTest : public FocusControllerDirectTestBase {
874 FocusControllerApiTest() {}
877 // Overridden from FocusControllerTestBase:
878 void FocusWindowDirect(aura::Window* window) override { FocusWindow(window); }
879 void ActivateWindowDirect(aura::Window* window) override {
880 ActivateWindow(window);
882 void DeactivateWindowDirect(aura::Window* window) override {
883 DeactivateWindow(window);
885 bool IsInputEvent() override { return false; }
887 DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest);
890 // Focus and Activation changes via input events.
891 class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
893 FocusControllerMouseEventTest() {}
895 // Tests that a handled mouse or gesture event does not trigger a window
897 void IgnoreHandledEvent() {
898 EXPECT_EQ(NULL, GetActiveWindow());
899 aura::Window* w1 = root_window()->GetChildById(1);
900 SimpleEventHandler handler;
901 root_window()->PrependPreTargetHandler(&handler);
902 ui::test::EventGenerator generator(root_window(), w1);
903 generator.ClickLeftButton();
904 EXPECT_EQ(NULL, GetActiveWindow());
905 generator.GestureTapAt(w1->bounds().CenterPoint());
906 EXPECT_EQ(NULL, GetActiveWindow());
907 root_window()->RemovePreTargetHandler(&handler);
908 generator.ClickLeftButton();
909 EXPECT_EQ(1, GetActiveWindowId());
913 // Overridden from FocusControllerTestBase:
914 void FocusWindowDirect(aura::Window* window) override {
915 ui::test::EventGenerator generator(root_window(), window);
916 generator.ClickLeftButton();
918 void ActivateWindowDirect(aura::Window* window) override {
919 ui::test::EventGenerator generator(root_window(), window);
920 generator.ClickLeftButton();
922 void DeactivateWindowDirect(aura::Window* window) override {
923 aura::Window* next_activatable =
924 test_focus_rules()->GetNextActivatableWindow(window);
925 ui::test::EventGenerator generator(root_window(), next_activatable);
926 generator.ClickLeftButton();
928 bool IsInputEvent() override { return true; }
930 DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest);
933 class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
935 FocusControllerGestureEventTest() {}
938 // Overridden from FocusControllerTestBase:
939 void FocusWindowDirect(aura::Window* window) override {
940 ui::test::EventGenerator generator(root_window(), window);
941 generator.GestureTapAt(window->bounds().CenterPoint());
943 void ActivateWindowDirect(aura::Window* window) override {
944 ui::test::EventGenerator generator(root_window(), window);
945 generator.GestureTapAt(window->bounds().CenterPoint());
947 void DeactivateWindowDirect(aura::Window* window) override {
948 aura::Window* next_activatable =
949 test_focus_rules()->GetNextActivatableWindow(window);
950 ui::test::EventGenerator generator(root_window(), next_activatable);
951 generator.GestureTapAt(window->bounds().CenterPoint());
953 bool IsInputEvent() override { return true; }
955 DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest);
958 // Test base for tests where focus is implicitly set to a window as the result
959 // of a disposition change to the focused window or the hierarchy that contains
961 class FocusControllerImplicitTestBase : public FocusControllerTestBase {
963 explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {}
965 aura::Window* GetDispositionWindow(aura::Window* window) {
966 return parent_ ? window->parent() : window;
969 // Change the disposition of |window| in such a way as it will lose focus.
970 virtual void ChangeWindowDisposition(aura::Window* window) = 0;
972 // Allow each disposition change test to add additional post-disposition
973 // change expectations.
974 virtual void PostDispostionChangeExpectations() {}
976 // Overridden from FocusControllerTestBase:
977 void BasicFocus() override {
978 EXPECT_EQ(NULL, GetFocusedWindow());
980 aura::Window* w211 = root_window()->GetChildById(211);
982 EXPECT_EQ(211, GetFocusedWindowId());
984 ChangeWindowDisposition(w211);
985 // BasicFocusRules passes focus to the parent.
986 EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId());
988 void BasicActivation() override {
989 DCHECK(!parent_) << "Activation tests don't support parent changes.";
991 EXPECT_EQ(NULL, GetActiveWindow());
993 aura::Window* w2 = root_window()->GetChildById(2);
995 EXPECT_EQ(2, GetActiveWindowId());
997 ChangeWindowDisposition(w2);
998 EXPECT_EQ(3, GetActiveWindowId());
999 PostDispostionChangeExpectations();
1001 void FocusEvents() override {
1002 aura::Window* w211 = root_window()->GetChildById(211);
1005 ScopedFocusNotificationObserver root_observer(root_window());
1006 ScopedTargetFocusNotificationObserver observer211(root_window(), 211);
1007 root_observer.ExpectCounts(0, 0);
1008 observer211.ExpectCounts(0, 0);
1010 ChangeWindowDisposition(w211);
1011 root_observer.ExpectCounts(0, 1);
1012 observer211.ExpectCounts(0, 1);
1014 void ActivationEvents() override {
1015 DCHECK(!parent_) << "Activation tests don't support parent changes.";
1017 aura::Window* w2 = root_window()->GetChildById(2);
1020 ScopedFocusNotificationObserver root_observer(root_window());
1021 ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
1022 ScopedTargetFocusNotificationObserver observer3(root_window(), 3);
1023 root_observer.ExpectCounts(0, 0);
1024 observer2.ExpectCounts(0, 0);
1025 observer3.ExpectCounts(0, 0);
1027 ChangeWindowDisposition(w2);
1028 root_observer.ExpectCounts(1, 1);
1029 observer2.ExpectCounts(1, 1);
1030 observer3.ExpectCounts(1, 1);
1032 void FocusRulesOverride() override {
1033 EXPECT_EQ(NULL, GetFocusedWindow());
1034 aura::Window* w211 = root_window()->GetChildById(211);
1036 EXPECT_EQ(211, GetFocusedWindowId());
1038 test_focus_rules()->set_focus_restriction(root_window()->GetChildById(11));
1039 ChangeWindowDisposition(w211);
1040 // Normally, focus would shift to the parent (w21) but the override shifts
1042 EXPECT_EQ(11, GetFocusedWindowId());
1044 test_focus_rules()->set_focus_restriction(NULL);
1046 void ActivationRulesOverride() override {
1047 DCHECK(!parent_) << "Activation tests don't support parent changes.";
1049 aura::Window* w1 = root_window()->GetChildById(1);
1052 EXPECT_EQ(1, GetActiveWindowId());
1053 EXPECT_EQ(1, GetFocusedWindowId());
1055 aura::Window* w3 = root_window()->GetChildById(3);
1056 test_focus_rules()->set_focus_restriction(w3);
1058 // Normally, activation/focus would move to w2, but since we have a focus
1059 // restriction, it should move to w3 instead.
1060 ChangeWindowDisposition(w1);
1061 EXPECT_EQ(3, GetActiveWindowId());
1062 EXPECT_EQ(3, GetFocusedWindowId());
1064 test_focus_rules()->set_focus_restriction(NULL);
1065 ActivateWindow(root_window()->GetChildById(2));
1066 EXPECT_EQ(2, GetActiveWindowId());
1067 EXPECT_EQ(2, GetFocusedWindowId());
1071 // When true, the disposition change occurs to the parent of the window
1072 // instead of to the window. This verifies that changes occurring in the
1073 // hierarchy that contains the window affect the window's focus.
1076 DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase);
1079 // Focus and Activation changes in response to window visibility changes.
1080 class FocusControllerHideTest : public FocusControllerImplicitTestBase {
1082 FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {}
1085 FocusControllerHideTest(bool parent)
1086 : FocusControllerImplicitTestBase(parent) {}
1088 // Overridden from FocusControllerImplicitTestBase:
1089 void ChangeWindowDisposition(aura::Window* window) override {
1090 GetDispositionWindow(window)->Hide();
1094 DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest);
1097 // Focus and Activation changes in response to window parent visibility
1099 class FocusControllerParentHideTest : public FocusControllerHideTest {
1101 FocusControllerParentHideTest() : FocusControllerHideTest(true) {}
1104 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest);
1107 // Focus and Activation changes in response to window destruction.
1108 class FocusControllerDestructionTest : public FocusControllerImplicitTestBase {
1110 FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {}
1113 FocusControllerDestructionTest(bool parent)
1114 : FocusControllerImplicitTestBase(parent) {}
1116 // Overridden from FocusControllerImplicitTestBase:
1117 void ChangeWindowDisposition(aura::Window* window) override {
1118 delete GetDispositionWindow(window);
1122 DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest);
1125 // Focus and Activation changes in response to window parent destruction.
1126 class FocusControllerParentDestructionTest
1127 : public FocusControllerDestructionTest {
1129 FocusControllerParentDestructionTest()
1130 : FocusControllerDestructionTest(true) {}
1133 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentDestructionTest);
1136 // Focus and Activation changes in response to window removal.
1137 class FocusControllerRemovalTest : public FocusControllerImplicitTestBase {
1139 FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {}
1142 FocusControllerRemovalTest(bool parent)
1143 : FocusControllerImplicitTestBase(parent) {}
1145 // Overridden from FocusControllerImplicitTestBase:
1146 void ChangeWindowDisposition(aura::Window* window) override {
1147 aura::Window* disposition_window = GetDispositionWindow(window);
1148 disposition_window->parent()->RemoveChild(disposition_window);
1149 window_owner_.reset(disposition_window);
1151 void TearDown() override {
1152 window_owner_.reset();
1153 FocusControllerImplicitTestBase::TearDown();
1157 scoped_ptr<aura::Window> window_owner_;
1159 DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest);
1162 // Focus and Activation changes in response to window parent removal.
1163 class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
1165 FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {}
1168 DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest);
1172 #define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
1173 TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }
1175 // Runs direct focus change tests (input events and API calls).
1176 #define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
1177 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \
1178 FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \
1179 FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME)
1181 // Runs implicit focus change tests for disposition changes to target.
1182 #define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
1183 FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \
1184 FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
1185 FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME)
1187 // Runs implicit focus change tests for disposition changes to target's parent
1189 #define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \
1190 /* TODO(beng): parent destruction tests are not supported at
1191 present due to workspace manager issues. \
1192 FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \
1193 FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \
1194 FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)
1196 // Runs all implicit focus change tests (changes to the target and target's
1197 // parent hierarchy)
1198 #define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \
1199 IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
1200 IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)
1202 // Runs all possible focus change tests.
1203 #define ALL_FOCUS_TESTS(TESTNAME) \
1204 DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
1205 IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)
1207 // Runs focus change tests that apply only to the target. For example,
1208 // implicit activation changes caused by window disposition changes do not
1209 // occur when changes to the containing hierarchy happen.
1210 #define TARGET_FOCUS_TESTS(TESTNAME) \
1211 DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
1212 IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)
1214 // - Focuses a window, verifies that focus changed.
1215 ALL_FOCUS_TESTS(BasicFocus);
1217 // - Activates a window, verifies that activation changed.
1218 TARGET_FOCUS_TESTS(BasicActivation);
1220 // - Focuses a window, verifies that focus events were dispatched.
1221 ALL_FOCUS_TESTS(FocusEvents);
1223 // - Focuses or activates a window multiple times, verifies that events are only
1224 // dispatched when focus/activation actually changes.
1225 DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents);
1226 DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents);
1228 // - Activates a window, verifies that activation events were dispatched.
1229 TARGET_FOCUS_TESTS(ActivationEvents);
1231 // - Attempts to active a hidden window, verifies that current window is
1232 // attempted to be reactivated and the appropriate event dispatched.
1233 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents);
1235 // - Input events/API calls shift focus between focusable windows within the
1237 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow);
1239 // - Input events/API calls to a child window of an inactive window shifts
1240 // activation to the activatable parent and focuses the child.
1241 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow);
1243 // - Input events/API calls to focus the parent of the focused window do not
1244 // shift focus away from the child.
1245 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow);
1247 // - Verifies that FocusRules determine what can be focused.
1248 ALL_FOCUS_TESTS(FocusRulesOverride);
1250 // - Verifies that FocusRules determine what can be activated.
1251 TARGET_FOCUS_TESTS(ActivationRulesOverride);
1253 // - Verifies that attempts to change focus or activation from a focus or
1254 // activation change observer are ignored.
1255 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation);
1256 DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide);
1257 DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation);
1259 // Clicking on a window which has capture should not result in a focus change.
1260 DIRECT_FOCUS_CHANGE_TESTS(NoFocusChangeOnClickOnCaptureWindow);
1262 FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
1263 ChangeFocusWhenNothingFocusedAndCaptured);
1265 // See description above DontPassDeletedWindow() for details.
1266 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow);
1268 // - Verifies that the focused text input client is cleard when the window focus
1270 ALL_FOCUS_TESTS(FocusedTextInputClient);
1272 // If a mouse event was handled, it should not activate a window.
1273 FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, IgnoreHandledEvent);