diff options
Diffstat (limited to 'chromium/ui/views/corewm/focus_controller_unittest.cc')
-rw-r--r-- | chromium/ui/views/corewm/focus_controller_unittest.cc | 1110 |
1 files changed, 0 insertions, 1110 deletions
diff --git a/chromium/ui/views/corewm/focus_controller_unittest.cc b/chromium/ui/views/corewm/focus_controller_unittest.cc deleted file mode 100644 index cfccd056c97..00000000000 --- a/chromium/ui/views/corewm/focus_controller_unittest.cc +++ /dev/null @@ -1,1110 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/corewm/focus_controller.h" - -#include <map> - -#include "ui/aura/client/activation_change_observer.h" -#include "ui/aura/client/activation_client.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/client/default_capture_client.h" -#include "ui/aura/client/focus_change_observer.h" -#include "ui/aura/root_window.h" -#include "ui/aura/test/aura_test_base.h" -#include "ui/aura/test/event_generator.h" -#include "ui/aura/test/test_window_delegate.h" -#include "ui/aura/test/test_windows.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tracker.h" -#include "ui/events/event_handler.h" -#include "ui/views/corewm/base_focus_rules.h" - -namespace views { -namespace corewm { - -class FocusNotificationObserver : public aura::client::ActivationChangeObserver, - public aura::client::FocusChangeObserver { - public: - FocusNotificationObserver() - : activation_changed_count_(0), - focus_changed_count_(0), - reactivation_count_(0), - reactivation_requested_window_(NULL), - reactivation_actual_window_(NULL) {} - virtual ~FocusNotificationObserver() {} - - void ExpectCounts(int activation_changed_count, int focus_changed_count) { - EXPECT_EQ(activation_changed_count, activation_changed_count_); - EXPECT_EQ(focus_changed_count, focus_changed_count_); - } - int reactivation_count() const { - return reactivation_count_; - } - aura::Window* reactivation_requested_window() const { - return reactivation_requested_window_; - } - aura::Window* reactivation_actual_window() const { - return reactivation_actual_window_; - } - - private: - // Overridden from aura::client::ActivationChangeObserver: - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - ++activation_changed_count_; - } - virtual void OnAttemptToReactivateWindow( - aura::Window* request_active, - aura::Window* actual_active) OVERRIDE { - ++reactivation_count_; - reactivation_requested_window_ = request_active; - reactivation_actual_window_ = actual_active; - } - - // Overridden from aura::client::FocusChangeObserver: - virtual void OnWindowFocused(aura::Window* gained_focus, - aura::Window* lost_focus) OVERRIDE { - ++focus_changed_count_; - } - - int activation_changed_count_; - int focus_changed_count_; - int reactivation_count_; - aura::Window* reactivation_requested_window_; - aura::Window* reactivation_actual_window_; - - DISALLOW_COPY_AND_ASSIGN(FocusNotificationObserver); -}; - -// ActivationChangeObserver that keeps a vector of all the windows that lost -// active. -class RecordingActivationChangeObserver - : public aura::client::ActivationChangeObserver { - public: - explicit RecordingActivationChangeObserver(aura::Window* root) - : root_(root) { - aura::client::GetActivationClient(root_)->AddObserver(this); - } - virtual ~RecordingActivationChangeObserver() { - aura::client::GetActivationClient(root_)->RemoveObserver(this); - } - - // Each time we get OnWindowActivated() the |lost_active| parameter is - // added here. - const std::vector<aura::Window*>& lost() const { return lost_; } - - // Overridden from aura::client::ActivationChangeObserver: - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - lost_.push_back(lost_active); - } - - private: - aura::Window* root_; - std::vector<aura::Window*> lost_; - - DISALLOW_COPY_AND_ASSIGN(RecordingActivationChangeObserver); -}; - -// ActivationChangeObserver that deletes the window losing activation. -class DeleteOnLoseActivationChangeObserver - : public aura::client::ActivationChangeObserver { - public: - explicit DeleteOnLoseActivationChangeObserver(aura::Window* window) - : root_(window->GetRootWindow()), - window_(window) { - aura::client::GetActivationClient(root_)->AddObserver(this); - } - virtual ~DeleteOnLoseActivationChangeObserver() { - aura::client::GetActivationClient(root_)->RemoveObserver(this); - } - - bool did_delete() const { return window_ == NULL; } - - // Overridden from aura::client::ActivationChangeObserver: - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - if (window_ && lost_active == window_) { - window_ = NULL; - delete lost_active; - } - } - - private: - aura::Window* root_; - aura::Window* window_; - - DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseActivationChangeObserver); -}; - -class ScopedFocusNotificationObserver : public FocusNotificationObserver { - public: - ScopedFocusNotificationObserver(aura::Window* root_window) - : root_window_(root_window) { - aura::client::GetActivationClient(root_window_)->AddObserver(this); - aura::client::GetFocusClient(root_window_)->AddObserver(this); - } - virtual ~ScopedFocusNotificationObserver() { - aura::client::GetActivationClient(root_window_)->RemoveObserver(this); - aura::client::GetFocusClient(root_window_)->RemoveObserver(this); - } - - private: - aura::Window* root_window_; - - DISALLOW_COPY_AND_ASSIGN(ScopedFocusNotificationObserver); -}; - -class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver { - public: - ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id) - : target_(root_window->GetChildById(id)) { - aura::client::SetActivationChangeObserver(target_, this); - aura::client::SetFocusChangeObserver(target_, this); - tracker_.Add(target_); - } - virtual ~ScopedTargetFocusNotificationObserver() { - if (tracker_.Contains(target_)) { - aura::client::SetActivationChangeObserver(target_, NULL); - aura::client::SetFocusChangeObserver(target_, NULL); - } - } - - private: - aura::Window* target_; - aura::WindowTracker tracker_; - - DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver); -}; - -class FocusShiftingActivationObserver - : public aura::client::ActivationChangeObserver { - public: - explicit FocusShiftingActivationObserver(aura::Window* activated_window) - : activated_window_(activated_window), - shift_focus_to_(NULL) {} - virtual ~FocusShiftingActivationObserver() {} - - void set_shift_focus_to(aura::Window* shift_focus_to) { - shift_focus_to_ = shift_focus_to; - } - - private: - // Overridden from aura::client::ActivationChangeObserver: - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - // Shift focus to a child. This should prevent the default focusing from - // occurring in FocusController::FocusWindow(). - if (gained_active == activated_window_) { - aura::client::FocusClient* client = - aura::client::GetFocusClient(gained_active); - client->FocusWindow(shift_focus_to_); - } - } - - aura::Window* activated_window_; - aura::Window* shift_focus_to_; - - DISALLOW_COPY_AND_ASSIGN(FocusShiftingActivationObserver); -}; - -// BaseFocusRules subclass that allows basic overrides of focus/activation to -// be tested. This is intended more as a test that the override system works at -// all, rather than as an exhaustive set of use cases, those should be covered -// in tests for those FocusRules implementations. -class TestFocusRules : public BaseFocusRules { - public: - TestFocusRules() : focus_restriction_(NULL) {} - - // Restricts focus and activation to this window and its child hierarchy. - void set_focus_restriction(aura::Window* focus_restriction) { - focus_restriction_ = focus_restriction; - } - - // Overridden from BaseFocusRules: - virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE { - // In FocusControllerTests, only the RootWindow has activatable children. - return window->GetRootWindow() == window; - } - virtual bool CanActivateWindow(aura::Window* window) const OVERRIDE { - // Restricting focus to a non-activatable child window means the activatable - // parent outside the focus restriction is activatable. - bool can_activate = - CanFocusOrActivate(window) || window->Contains(focus_restriction_); - return can_activate ? BaseFocusRules::CanActivateWindow(window) : false; - } - virtual bool CanFocusWindow(aura::Window* window) const OVERRIDE { - return CanFocusOrActivate(window) ? - BaseFocusRules::CanFocusWindow(window) : false; - } - virtual aura::Window* GetActivatableWindow( - aura::Window* window) const OVERRIDE { - return BaseFocusRules::GetActivatableWindow( - CanFocusOrActivate(window) ? window : focus_restriction_); - } - virtual aura::Window* GetFocusableWindow( - aura::Window* window) const OVERRIDE { - return BaseFocusRules::GetFocusableWindow( - CanFocusOrActivate(window) ? window : focus_restriction_); - } - virtual aura::Window* GetNextActivatableWindow( - aura::Window* ignore) const OVERRIDE { - aura::Window* next_activatable = - BaseFocusRules::GetNextActivatableWindow(ignore); - return CanFocusOrActivate(next_activatable) ? - next_activatable : GetActivatableWindow(focus_restriction_); - } - - private: - bool CanFocusOrActivate(aura::Window* window) const { - return !focus_restriction_ || focus_restriction_->Contains(window); - } - - aura::Window* focus_restriction_; - - DISALLOW_COPY_AND_ASSIGN(TestFocusRules); -}; - -// Common infrastructure shared by all FocusController test types. -class FocusControllerTestBase : public aura::test::AuraTestBase { - protected: - FocusControllerTestBase() {} - - // Overridden from aura::test::AuraTestBase: - virtual void SetUp() OVERRIDE { - // FocusController registers itself as an Env observer so it can catch all - // window initializations, including the root_window()'s, so we create it - // before allowing the base setup. - test_focus_rules_ = new TestFocusRules; - focus_controller_.reset(new FocusController(test_focus_rules_)); - aura::test::AuraTestBase::SetUp(); - root_window()->AddPreTargetHandler(focus_controller_.get()); - aura::client::SetFocusClient(root_window(), focus_controller_.get()); - aura::client::SetActivationClient(root_window(), focus_controller_.get()); - - // Hierarchy used by all tests: - // root_window - // +-- w1 - // | +-- w11 - // | +-- w12 - // +-- w2 - // | +-- w21 - // | +-- w211 - // +-- w3 - aura::Window* w1 = aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1, - gfx::Rect(0, 0, 50, 50), root_window()); - aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 11, - gfx::Rect(5, 5, 10, 10), w1); - aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 12, - gfx::Rect(15, 15, 10, 10), w1); - aura::Window* w2 = aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 2, - gfx::Rect(75, 75, 50, 50), root_window()); - aura::Window* w21 = aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 21, - gfx::Rect(5, 5, 10, 10), w2); - aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 211, - gfx::Rect(1, 1, 5, 5), w21); - aura::test::CreateTestWindowWithDelegate( - aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 3, - gfx::Rect(125, 125, 50, 50), root_window()); - } - virtual void TearDown() OVERRIDE { - root_window()->RemovePreTargetHandler(focus_controller_.get()); - aura::test::AuraTestBase::TearDown(); - test_focus_rules_ = NULL; // Owned by FocusController. - focus_controller_.reset(); - } - - void FocusWindow(aura::Window* window) { - aura::client::GetFocusClient(root_window())->FocusWindow(window); - } - aura::Window* GetFocusedWindow() { - return aura::client::GetFocusClient(root_window())->GetFocusedWindow(); - } - int GetFocusedWindowId() { - aura::Window* focused_window = GetFocusedWindow(); - return focused_window ? focused_window->id() : -1; - } - void ActivateWindow(aura::Window* window) { - aura::client::GetActivationClient(root_window())->ActivateWindow(window); - } - void DeactivateWindow(aura::Window* window) { - aura::client::GetActivationClient(root_window())->DeactivateWindow(window); - } - aura::Window* GetActiveWindow() { - return aura::client::GetActivationClient(root_window())->GetActiveWindow(); - } - int GetActiveWindowId() { - aura::Window* active_window = GetActiveWindow(); - return active_window ? active_window->id() : -1; - } - - TestFocusRules* test_focus_rules() { return test_focus_rules_; } - - // Test functions. - virtual void BasicFocus() = 0; - virtual void BasicActivation() = 0; - virtual void FocusEvents() = 0; - virtual void DuplicateFocusEvents() {} - virtual void ActivationEvents() = 0; - virtual void ReactivationEvents() {} - virtual void DuplicateActivationEvents() {} - virtual void ShiftFocusWithinActiveWindow() {} - virtual void ShiftFocusToChildOfInactiveWindow() {} - virtual void ShiftFocusToParentOfFocusedWindow() {} - virtual void FocusRulesOverride() = 0; - virtual void ActivationRulesOverride() = 0; - virtual void ShiftFocusOnActivation() {} - virtual void ShiftFocusOnActivationDueToHide() {} - virtual void NoShiftActiveOnActivation() {} - virtual void NoFocusChangeOnClickOnCaptureWindow() {} - virtual void ChangeFocusWhenNothingFocusedAndCaptured() {} - virtual void DontPassDeletedWindow() {} - - private: - scoped_ptr<FocusController> focus_controller_; - TestFocusRules* test_focus_rules_; - - DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase); -}; - -// Test base for tests where focus is directly set to a target window. -class FocusControllerDirectTestBase : public FocusControllerTestBase { - protected: - FocusControllerDirectTestBase() {} - - // Different test types shift focus in different ways. - virtual void FocusWindowDirect(aura::Window* window) = 0; - virtual void ActivateWindowDirect(aura::Window* window) = 0; - virtual void DeactivateWindowDirect(aura::Window* window) = 0; - - // Input events do not change focus if the window can not be focused. - virtual bool IsInputEvent() = 0; - - void FocusWindowById(int id) { - aura::Window* window = root_window()->GetChildById(id); - DCHECK(window); - FocusWindowDirect(window); - } - void ActivateWindowById(int id) { - aura::Window* window = root_window()->GetChildById(id); - DCHECK(window); - ActivateWindowDirect(window); - } - - // Overridden from FocusControllerTestBase: - virtual void BasicFocus() OVERRIDE { - EXPECT_EQ(NULL, GetFocusedWindow()); - FocusWindowById(1); - EXPECT_EQ(1, GetFocusedWindowId()); - FocusWindowById(2); - EXPECT_EQ(2, GetFocusedWindowId()); - } - virtual void BasicActivation() OVERRIDE { - EXPECT_EQ(NULL, GetActiveWindow()); - ActivateWindowById(1); - EXPECT_EQ(1, GetActiveWindowId()); - ActivateWindowById(2); - EXPECT_EQ(2, GetActiveWindowId()); - // Verify that attempting to deactivate NULL does not crash and does not - // change activation. - DeactivateWindow(NULL); - EXPECT_EQ(2, GetActiveWindowId()); - DeactivateWindow(GetActiveWindow()); - EXPECT_EQ(1, GetActiveWindowId()); - } - virtual void FocusEvents() OVERRIDE { - ScopedFocusNotificationObserver root_observer(root_window()); - ScopedTargetFocusNotificationObserver observer1(root_window(), 1); - ScopedTargetFocusNotificationObserver observer2(root_window(), 2); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - - FocusWindowById(1); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(0, 0); - - FocusWindowById(2); - root_observer.ExpectCounts(2, 2); - observer1.ExpectCounts(2, 2); - observer2.ExpectCounts(1, 1); - } - virtual void DuplicateFocusEvents() OVERRIDE { - // Focusing an existing focused window should not resend focus events. - ScopedFocusNotificationObserver root_observer(root_window()); - ScopedTargetFocusNotificationObserver observer1(root_window(), 1); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - - FocusWindowById(1); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - - FocusWindowById(1); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - } - virtual void ActivationEvents() OVERRIDE { - ActivateWindowById(1); - - ScopedFocusNotificationObserver root_observer(root_window()); - ScopedTargetFocusNotificationObserver observer1(root_window(), 1); - ScopedTargetFocusNotificationObserver observer2(root_window(), 2); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - - ActivateWindowById(2); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - } - virtual void ReactivationEvents() OVERRIDE { - ActivateWindowById(1); - ScopedFocusNotificationObserver root_observer(root_window()); - EXPECT_EQ(0, root_observer.reactivation_count()); - root_window()->GetChildById(2)->Hide(); - // When we attempt to activate "2", which cannot be activated because it - // is not visible, "1" will be reactivated. - ActivateWindowById(2); - EXPECT_EQ(1, root_observer.reactivation_count()); - EXPECT_EQ(root_window()->GetChildById(2), - root_observer.reactivation_requested_window()); - EXPECT_EQ(root_window()->GetChildById(1), - root_observer.reactivation_actual_window()); - } - virtual void DuplicateActivationEvents() OVERRIDE { - // Activating an existing active window should not resend activation events. - ActivateWindowById(1); - - ScopedFocusNotificationObserver root_observer(root_window()); - ScopedTargetFocusNotificationObserver observer1(root_window(), 1); - ScopedTargetFocusNotificationObserver observer2(root_window(), 2); - - root_observer.ExpectCounts(0, 0); - observer1.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - - ActivateWindowById(2); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - - ActivateWindowById(2); - root_observer.ExpectCounts(1, 1); - observer1.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - } - virtual void ShiftFocusWithinActiveWindow() OVERRIDE { - ActivateWindowById(1); - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - FocusWindowById(11); - EXPECT_EQ(11, GetFocusedWindowId()); - FocusWindowById(12); - EXPECT_EQ(12, GetFocusedWindowId()); - } - virtual void ShiftFocusToChildOfInactiveWindow() OVERRIDE { - ActivateWindowById(2); - EXPECT_EQ(2, GetActiveWindowId()); - EXPECT_EQ(2, GetFocusedWindowId()); - FocusWindowById(11); - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(11, GetFocusedWindowId()); - } - virtual void ShiftFocusToParentOfFocusedWindow() OVERRIDE { - ActivateWindowById(1); - EXPECT_EQ(1, GetFocusedWindowId()); - FocusWindowById(11); - EXPECT_EQ(11, GetFocusedWindowId()); - FocusWindowById(1); - // Focus should _not_ shift to the parent of the already-focused window. - EXPECT_EQ(11, GetFocusedWindowId()); - } - virtual void FocusRulesOverride() OVERRIDE { - EXPECT_EQ(NULL, GetFocusedWindow()); - FocusWindowById(11); - EXPECT_EQ(11, GetFocusedWindowId()); - - test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211)); - FocusWindowById(12); - // Input events leave focus unchanged; direct API calls will change focus - // to the restricted window. - int focused_window = IsInputEvent() ? 11 : 211; - EXPECT_EQ(focused_window, GetFocusedWindowId()); - - test_focus_rules()->set_focus_restriction(NULL); - FocusWindowById(12); - EXPECT_EQ(12, GetFocusedWindowId()); - } - virtual void ActivationRulesOverride() OVERRIDE { - ActivateWindowById(1); - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - - aura::Window* w3 = root_window()->GetChildById(3); - test_focus_rules()->set_focus_restriction(w3); - - ActivateWindowById(2); - // Input events leave activation unchanged; direct API calls will activate - // the restricted window. - int active_window = IsInputEvent() ? 1 : 3; - EXPECT_EQ(active_window, GetActiveWindowId()); - EXPECT_EQ(active_window, GetFocusedWindowId()); - - test_focus_rules()->set_focus_restriction(NULL); - ActivateWindowById(2); - EXPECT_EQ(2, GetActiveWindowId()); - EXPECT_EQ(2, GetFocusedWindowId()); - } - virtual void ShiftFocusOnActivation() OVERRIDE { - // When a window is activated, by default that window is also focused. - // An ActivationChangeObserver may shift focus to another window within the - // same activatable window. - ActivateWindowById(2); - EXPECT_EQ(2, GetFocusedWindowId()); - ActivateWindowById(1); - EXPECT_EQ(1, GetFocusedWindowId()); - - ActivateWindowById(2); - - aura::Window* target = root_window()->GetChildById(1); - aura::client::ActivationClient* client = - aura::client::GetActivationClient(root_window()); - - scoped_ptr<FocusShiftingActivationObserver> observer( - new FocusShiftingActivationObserver(target)); - observer->set_shift_focus_to(target->GetChildById(11)); - client->AddObserver(observer.get()); - - ActivateWindowById(1); - - // w1's ActivationChangeObserver shifted focus to this child, pre-empting - // FocusController's default setting. - EXPECT_EQ(11, GetFocusedWindowId()); - - ActivateWindowById(2); - EXPECT_EQ(2, GetFocusedWindowId()); - - // Simulate a focus reset by the ActivationChangeObserver. This should - // trigger the default setting in FocusController. - observer->set_shift_focus_to(NULL); - ActivateWindowById(1); - EXPECT_EQ(1, GetFocusedWindowId()); - - client->RemoveObserver(observer.get()); - - ActivateWindowById(2); - EXPECT_EQ(2, GetFocusedWindowId()); - ActivateWindowById(1); - EXPECT_EQ(1, GetFocusedWindowId()); - } - virtual void ShiftFocusOnActivationDueToHide() OVERRIDE { - // Similar to ShiftFocusOnActivation except the activation change is - // triggered by hiding the active window. - ActivateWindowById(1); - EXPECT_EQ(1, GetFocusedWindowId()); - - // Removes window 3 as candidate for next activatable window. - root_window()->GetChildById(3)->Hide(); - EXPECT_EQ(1, GetFocusedWindowId()); - - aura::Window* target = root_window()->GetChildById(2); - aura::client::ActivationClient* client = - aura::client::GetActivationClient(root_window()); - - scoped_ptr<FocusShiftingActivationObserver> observer( - new FocusShiftingActivationObserver(target)); - observer->set_shift_focus_to(target->GetChildById(21)); - client->AddObserver(observer.get()); - - // Hide the active window. - root_window()->GetChildById(1)->Hide(); - - EXPECT_EQ(21, GetFocusedWindowId()); - - client->RemoveObserver(observer.get()); - } - virtual void NoShiftActiveOnActivation() OVERRIDE { - // When a window is activated, we need to prevent any change to activation - // from being made in response to an activation change notification. - } - - virtual void NoFocusChangeOnClickOnCaptureWindow() OVERRIDE { - scoped_ptr<aura::client::DefaultCaptureClient> capture_client( - new aura::client::DefaultCaptureClient(root_window())); - // Clicking on a window which has capture should not cause a focus change - // to the window. This test verifies whether that is indeed the case. - ActivateWindowById(1); - - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - - aura::Window* w2 = root_window()->GetChildById(2); - aura::client::GetCaptureClient(root_window())->SetCapture(w2); - aura::test::EventGenerator generator(root_window(), w2); - generator.ClickLeftButton(); - - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - aura::client::GetCaptureClient(root_window())->ReleaseCapture(w2); - } - - // Verifies focus change is honored while capture held. - virtual void ChangeFocusWhenNothingFocusedAndCaptured() OVERRIDE { - scoped_ptr<aura::client::DefaultCaptureClient> capture_client( - new aura::client::DefaultCaptureClient(root_window())); - aura::Window* w1 = root_window()->GetChildById(1); - aura::client::GetCaptureClient(root_window())->SetCapture(w1); - - EXPECT_EQ(-1, GetActiveWindowId()); - EXPECT_EQ(-1, GetFocusedWindowId()); - - FocusWindowById(1); - - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - - aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1); - } - - // Verfies if a window that loses activation is deleted during observer - // notification we don't pass the deleted window to other observers. - virtual void DontPassDeletedWindow() OVERRIDE { - FocusWindowById(1); - - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - - DeleteOnLoseActivationChangeObserver observer1( - root_window()->GetChildById(1)); - RecordingActivationChangeObserver observer2(root_window()); - - FocusWindowById(2); - - EXPECT_EQ(2, GetActiveWindowId()); - EXPECT_EQ(2, GetFocusedWindowId()); - - EXPECT_TRUE(observer1.did_delete()); - ASSERT_EQ(1u, observer2.lost().size()); - EXPECT_TRUE(observer2.lost()[0] == NULL); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase); -}; - -// Focus and Activation changes via aura::client::ActivationClient API. -class FocusControllerApiTest : public FocusControllerDirectTestBase { - public: - FocusControllerApiTest() {} - - private: - // Overridden from FocusControllerTestBase: - virtual void FocusWindowDirect(aura::Window* window) OVERRIDE { - FocusWindow(window); - } - virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE { - ActivateWindow(window); - } - virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE { - DeactivateWindow(window); - } - virtual bool IsInputEvent() OVERRIDE { return false; } - - DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest); -}; - -// Focus and Activation changes via input events. -class FocusControllerMouseEventTest : public FocusControllerDirectTestBase { - public: - FocusControllerMouseEventTest() {} - - private: - // Overridden from FocusControllerTestBase: - virtual void FocusWindowDirect(aura::Window* window) OVERRIDE { - aura::test::EventGenerator generator(root_window(), window); - generator.ClickLeftButton(); - } - virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE { - aura::test::EventGenerator generator(root_window(), window); - generator.ClickLeftButton(); - } - virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE { - aura::Window* next_activatable = - test_focus_rules()->GetNextActivatableWindow(window); - aura::test::EventGenerator generator(root_window(), next_activatable); - generator.ClickLeftButton(); - } - virtual bool IsInputEvent() OVERRIDE { return true; } - - DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest); -}; - -class FocusControllerGestureEventTest : public FocusControllerDirectTestBase { - public: - FocusControllerGestureEventTest() {} - - private: - // Overridden from FocusControllerTestBase: - virtual void FocusWindowDirect(aura::Window* window) OVERRIDE { - aura::test::EventGenerator generator(root_window(), window); - generator.GestureTapAt(window->bounds().CenterPoint()); - } - virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE { - aura::test::EventGenerator generator(root_window(), window); - generator.GestureTapAt(window->bounds().CenterPoint()); - } - virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE { - aura::Window* next_activatable = - test_focus_rules()->GetNextActivatableWindow(window); - aura::test::EventGenerator generator(root_window(), next_activatable); - generator.GestureTapAt(window->bounds().CenterPoint()); - } - virtual bool IsInputEvent() OVERRIDE { return true; } - - DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest); -}; - -// Test base for tests where focus is implicitly set to a window as the result -// of a disposition change to the focused window or the hierarchy that contains -// it. -class FocusControllerImplicitTestBase : public FocusControllerTestBase { - protected: - explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {} - - aura::Window* GetDispositionWindow(aura::Window* window) { - return parent_ ? window->parent() : window; - } - - // Change the disposition of |window| in such a way as it will lose focus. - virtual void ChangeWindowDisposition(aura::Window* window) = 0; - - // Allow each disposition change test to add additional post-disposition - // change expectations. - virtual void PostDispostionChangeExpectations() {} - - // Overridden from FocusControllerTestBase: - virtual void BasicFocus() OVERRIDE { - EXPECT_EQ(NULL, GetFocusedWindow()); - - aura::Window* w211 = root_window()->GetChildById(211); - FocusWindow(w211); - EXPECT_EQ(211, GetFocusedWindowId()); - - ChangeWindowDisposition(w211); - // BasicFocusRules passes focus to the parent. - EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId()); - } - virtual void BasicActivation() OVERRIDE { - DCHECK(!parent_) << "Activation tests don't support parent changes."; - - EXPECT_EQ(NULL, GetActiveWindow()); - - aura::Window* w2 = root_window()->GetChildById(2); - ActivateWindow(w2); - EXPECT_EQ(2, GetActiveWindowId()); - - ChangeWindowDisposition(w2); - EXPECT_EQ(3, GetActiveWindowId()); - PostDispostionChangeExpectations(); - } - virtual void FocusEvents() OVERRIDE { - aura::Window* w211 = root_window()->GetChildById(211); - FocusWindow(w211); - - ScopedFocusNotificationObserver root_observer(root_window()); - ScopedTargetFocusNotificationObserver observer211(root_window(), 211); - root_observer.ExpectCounts(0, 0); - observer211.ExpectCounts(0, 0); - - ChangeWindowDisposition(w211); - root_observer.ExpectCounts(0, 1); - observer211.ExpectCounts(0, 1); - } - virtual void ActivationEvents() OVERRIDE { - DCHECK(!parent_) << "Activation tests don't support parent changes."; - - aura::Window* w2 = root_window()->GetChildById(2); - ActivateWindow(w2); - - ScopedFocusNotificationObserver root_observer(root_window()); - ScopedTargetFocusNotificationObserver observer2(root_window(), 2); - ScopedTargetFocusNotificationObserver observer3(root_window(), 3); - root_observer.ExpectCounts(0, 0); - observer2.ExpectCounts(0, 0); - observer3.ExpectCounts(0, 0); - - ChangeWindowDisposition(w2); - root_observer.ExpectCounts(1, 1); - observer2.ExpectCounts(1, 1); - observer3.ExpectCounts(1, 1); - } - virtual void FocusRulesOverride() OVERRIDE { - EXPECT_EQ(NULL, GetFocusedWindow()); - aura::Window* w211 = root_window()->GetChildById(211); - FocusWindow(w211); - EXPECT_EQ(211, GetFocusedWindowId()); - - test_focus_rules()->set_focus_restriction(root_window()->GetChildById(11)); - ChangeWindowDisposition(w211); - // Normally, focus would shift to the parent (w21) but the override shifts - // it to 11. - EXPECT_EQ(11, GetFocusedWindowId()); - - test_focus_rules()->set_focus_restriction(NULL); - } - virtual void ActivationRulesOverride() OVERRIDE { - DCHECK(!parent_) << "Activation tests don't support parent changes."; - - aura::Window* w1 = root_window()->GetChildById(1); - ActivateWindow(w1); - - EXPECT_EQ(1, GetActiveWindowId()); - EXPECT_EQ(1, GetFocusedWindowId()); - - aura::Window* w3 = root_window()->GetChildById(3); - test_focus_rules()->set_focus_restriction(w3); - - // Normally, activation/focus would move to w2, but since we have a focus - // restriction, it should move to w3 instead. - ChangeWindowDisposition(w1); - EXPECT_EQ(3, GetActiveWindowId()); - EXPECT_EQ(3, GetFocusedWindowId()); - - test_focus_rules()->set_focus_restriction(NULL); - ActivateWindow(root_window()->GetChildById(2)); - EXPECT_EQ(2, GetActiveWindowId()); - EXPECT_EQ(2, GetFocusedWindowId()); - } - - private: - // When true, the disposition change occurs to the parent of the window - // instead of to the window. This verifies that changes occurring in the - // hierarchy that contains the window affect the window's focus. - bool parent_; - - DISALLOW_COPY_AND_ASSIGN(FocusControllerImplicitTestBase); -}; - -// Focus and Activation changes in response to window visibility changes. -class FocusControllerHideTest : public FocusControllerImplicitTestBase { - public: - FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {} - - protected: - FocusControllerHideTest(bool parent) - : FocusControllerImplicitTestBase(parent) {} - - // Overridden from FocusControllerImplicitTestBase: - virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE { - GetDispositionWindow(window)->Hide(); - } - virtual void PostDispostionChangeExpectations() OVERRIDE { - // BasicActivation() starts with the stacking order: 1, 2, 3 (3 topmost) - // and then activates 2. After 2 is hidden in ChangeWindowDisposition - // above, 3 is activated, but code in - // FocusController::OnWindowVisibilityChanging keeps 2's layer above 3's - // until a hide animation completes (e.g. a fade-out transition). - aura::Window* w2 = root_window()->GetChildById(2); - aura::Window* w3 = root_window()->GetChildById(3); - - // W2 was hidden, but its layer should still be stacked above W3's. - typedef std::vector<ui::Layer*> Layers; - const Layers& children = w3->parent()->layer()->children(); - Layers::const_iterator w3_iter = - std::find(children.begin(), children.end(), w3->layer()); - Layers::const_iterator w2_iter = - std::find(children.begin(), children.end(), w2->layer()); - EXPECT_TRUE(w2_iter > w3_iter); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerHideTest); -}; - -// Focus and Activation changes in response to window parent visibility -// changes. -class FocusControllerParentHideTest : public FocusControllerHideTest { - public: - FocusControllerParentHideTest() : FocusControllerHideTest(true) {} - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerParentHideTest); -}; - -// Focus and Activation changes in response to window destruction. -class FocusControllerDestructionTest : public FocusControllerImplicitTestBase { - public: - FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {} - - protected: - FocusControllerDestructionTest(bool parent) - : FocusControllerImplicitTestBase(parent) {} - - // Overridden from FocusControllerImplicitTestBase: - virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE { - delete GetDispositionWindow(window); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerDestructionTest); -}; - -// Focus and Activation changes in response to window parent destruction. -class FocusControllerParentDestructionTest - : public FocusControllerDestructionTest { - public: - FocusControllerParentDestructionTest() - : FocusControllerDestructionTest(true) {} - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerParentDestructionTest); -}; - -// Focus and Activation changes in response to window removal. -class FocusControllerRemovalTest : public FocusControllerImplicitTestBase { - public: - FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {} - - protected: - FocusControllerRemovalTest(bool parent) - : FocusControllerImplicitTestBase(parent) {} - - // Overridden from FocusControllerImplicitTestBase: - virtual void ChangeWindowDisposition(aura::Window* window) OVERRIDE { - aura::Window* disposition_window = GetDispositionWindow(window); - disposition_window->parent()->RemoveChild(disposition_window); - window_owner_.reset(disposition_window); - } - virtual void TearDown() OVERRIDE { - window_owner_.reset(); - FocusControllerImplicitTestBase::TearDown(); - } - - private: - scoped_ptr<aura::Window> window_owner_; - - DISALLOW_COPY_AND_ASSIGN(FocusControllerRemovalTest); -}; - -// Focus and Activation changes in response to window parent removal. -class FocusControllerParentRemovalTest : public FocusControllerRemovalTest { - public: - FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {} - - private: - DISALLOW_COPY_AND_ASSIGN(FocusControllerParentRemovalTest); -}; - - -#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \ - TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); } - -// Runs direct focus change tests (input events and API calls). -#define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME) - -// Runs implicit focus change tests for disposition changes to target. -#define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME) - -// Runs implicit focus change tests for disposition changes to target's parent -// hierarchy. -#define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \ - /* TODO(beng): parent destruction tests are not supported at - present due to workspace manager issues. \ - FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \ - FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \ - FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME) - -// Runs all implicit focus change tests (changes to the target and target's -// parent hierarchy) -#define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) - -// Runs all possible focus change tests. -#define ALL_FOCUS_TESTS(TESTNAME) \ - DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) - -// Runs focus change tests that apply only to the target. For example, -// implicit activation changes caused by window disposition changes do not -// occur when changes to the containing hierarchy happen. -#define TARGET_FOCUS_TESTS(TESTNAME) \ - DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \ - IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) - -// - Focuses a window, verifies that focus changed. -ALL_FOCUS_TESTS(BasicFocus); - -// - Activates a window, verifies that activation changed. -TARGET_FOCUS_TESTS(BasicActivation); - -// - Focuses a window, verifies that focus events were dispatched. -ALL_FOCUS_TESTS(FocusEvents); - -// - Focuses or activates a window multiple times, verifies that events are only -// dispatched when focus/activation actually changes. -DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents); -DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents); - -// - Activates a window, verifies that activation events were dispatched. -TARGET_FOCUS_TESTS(ActivationEvents); - -// - Attempts to active a hidden window, verifies that current window is -// attempted to be reactivated and the appropriate event dispatched. -FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents); - -// - Input events/API calls shift focus between focusable windows within the -// active window. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow); - -// - Input events/API calls to a child window of an inactive window shifts -// activation to the activatable parent and focuses the child. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow); - -// - Input events/API calls to focus the parent of the focused window do not -// shift focus away from the child. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow); - -// - Verifies that FocusRules determine what can be focused. -ALL_FOCUS_TESTS(FocusRulesOverride); - -// - Verifies that FocusRules determine what can be activated. -TARGET_FOCUS_TESTS(ActivationRulesOverride); - -// - Verifies that attempts to change focus or activation from a focus or -// activation change observer are ignored. -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation); -DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide); -DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation); - -// Clicking on a window which has capture should not result in a focus change. -DIRECT_FOCUS_CHANGE_TESTS(NoFocusChangeOnClickOnCaptureWindow); - -FOCUS_CONTROLLER_TEST(FocusControllerApiTest, - ChangeFocusWhenNothingFocusedAndCaptured); - -// See description above DontPassDeletedWindow() for details. -FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow); - -} // namespace corewm -} // namespace views |