root/ui/wm/core/focus_controller_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reactivation_actual_window_
  2. ExpectCounts
  3. reactivation_count
  4. reactivation_requested_window
  5. reactivation_actual_window
  6. OnWindowActivated
  7. OnAttemptToReactivateWindow
  8. OnWindowFocused
  9. was_notified_with_deleted_window_
  10. was_notified_with_deleted_window
  11. OnWindowActivated
  12. OnWindowFocused
  13. did_delete_
  14. OnWindowActivated
  15. GetDeletedWindow
  16. did_delete_
  17. OnWindowFocused
  18. GetDeletedWindow
  19. shift_focus_to_
  20. set_shift_focus_to
  21. OnWindowActivated
  22. set_focus_restriction
  23. SupportsChildActivation
  24. CanActivateWindow
  25. CanFocusWindow
  26. GetActivatableWindow
  27. GetFocusableWindow
  28. GetNextActivatableWindow
  29. CanFocusOrActivate
  30. SetUp
  31. TearDown
  32. FocusWindow
  33. GetFocusedWindow
  34. GetFocusedWindowId
  35. ActivateWindow
  36. DeactivateWindow
  37. GetActiveWindow
  38. GetActiveWindowId
  39. test_focus_rules
  40. DuplicateFocusEvents
  41. ReactivationEvents
  42. DuplicateActivationEvents
  43. ShiftFocusWithinActiveWindow
  44. ShiftFocusToChildOfInactiveWindow
  45. ShiftFocusToParentOfFocusedWindow
  46. ShiftFocusOnActivation
  47. ShiftFocusOnActivationDueToHide
  48. NoShiftActiveOnActivation
  49. NoFocusChangeOnClickOnCaptureWindow
  50. ChangeFocusWhenNothingFocusedAndCaptured
  51. DontPassDeletedWindow
  52. FocusWindowById
  53. ActivateWindowById
  54. BasicFocus
  55. BasicActivation
  56. FocusEvents
  57. DuplicateFocusEvents
  58. ActivationEvents
  59. ReactivationEvents
  60. DuplicateActivationEvents
  61. ShiftFocusWithinActiveWindow
  62. ShiftFocusToChildOfInactiveWindow
  63. ShiftFocusToParentOfFocusedWindow
  64. FocusRulesOverride
  65. ActivationRulesOverride
  66. ShiftFocusOnActivation
  67. ShiftFocusOnActivationDueToHide
  68. NoShiftActiveOnActivation
  69. NoFocusChangeOnClickOnCaptureWindow
  70. ChangeFocusWhenNothingFocusedAndCaptured
  71. DontPassDeletedWindow
  72. FocusWindowDirect
  73. ActivateWindowDirect
  74. DeactivateWindowDirect
  75. IsInputEvent
  76. FocusWindowDirect
  77. ActivateWindowDirect
  78. DeactivateWindowDirect
  79. IsInputEvent
  80. FocusWindowDirect
  81. ActivateWindowDirect
  82. DeactivateWindowDirect
  83. IsInputEvent
  84. GetDispositionWindow
  85. PostDispostionChangeExpectations
  86. BasicFocus
  87. BasicActivation
  88. FocusEvents
  89. ActivationEvents
  90. FocusRulesOverride
  91. ActivationRulesOverride
  92. ChangeWindowDisposition
  93. ChangeWindowDisposition
  94. ChangeWindowDisposition
  95. TearDown

// 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/wm/core/focus_controller.h"

#include <map>

#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/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_event_dispatcher.h"
#include "ui/aura/window_tracker.h"
#include "ui/events/event_handler.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/wm_state.h"
#include "ui/wm/public/activation_change_observer.h"
#include "ui/wm/public/activation_client.h"

namespace wm {

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);
};

class WindowDeleter {
 public:
  virtual aura::Window* GetDeletedWindow() = 0;

 protected:
  virtual ~WindowDeleter() {}
};

// ActivationChangeObserver and FocusChangeObserver that keeps track of whether
// it was notified about activation changes or focus changes with a deleted
// window.
class RecordingActivationAndFocusChangeObserver
    : public aura::client::ActivationChangeObserver,
      public aura::client::FocusChangeObserver {
 public:
  RecordingActivationAndFocusChangeObserver(aura::Window* root,
                                            WindowDeleter* deleter)
      : root_(root),
        deleter_(deleter),
        was_notified_with_deleted_window_(false) {
    aura::client::GetActivationClient(root_)->AddObserver(this);
    aura::client::GetFocusClient(root_)->AddObserver(this);
  }
  virtual ~RecordingActivationAndFocusChangeObserver() {
    aura::client::GetActivationClient(root_)->RemoveObserver(this);
    aura::client::GetFocusClient(root_)->RemoveObserver(this);
  }

  bool was_notified_with_deleted_window() const {
    return was_notified_with_deleted_window_;
  }

  // Overridden from aura::client::ActivationChangeObserver:
  virtual void OnWindowActivated(aura::Window* gained_active,
                                 aura::Window* lost_active) OVERRIDE {
    if (lost_active && lost_active == deleter_->GetDeletedWindow())
      was_notified_with_deleted_window_ = true;
  }

  // Overridden from aura::client::FocusChangeObserver:
  virtual void OnWindowFocused(aura::Window* gained_focus,
                               aura::Window* lost_focus) OVERRIDE {
    if (lost_focus && lost_focus == deleter_->GetDeletedWindow())
      was_notified_with_deleted_window_ = true;
  }

 private:
  aura::Window* root_;

  // Not owned.
  WindowDeleter* deleter_;

  // Whether the observer was notified about the loss of activation or the
  // loss of focus with a window already deleted by |deleter_| as the
  // |lost_active| or |lost_focus| parameter.
  bool was_notified_with_deleted_window_;

  DISALLOW_COPY_AND_ASSIGN(RecordingActivationAndFocusChangeObserver);
};

// ActivationChangeObserver that deletes the window losing activation.
class DeleteOnLoseActivationChangeObserver :
    public aura::client::ActivationChangeObserver,
    public WindowDeleter {
 public:
  explicit DeleteOnLoseActivationChangeObserver(aura::Window* window)
      : root_(window->GetRootWindow()),
        window_(window),
        did_delete_(false) {
    aura::client::GetActivationClient(root_)->AddObserver(this);
  }
  virtual ~DeleteOnLoseActivationChangeObserver() {
    aura::client::GetActivationClient(root_)->RemoveObserver(this);
  }

  // Overridden from aura::client::ActivationChangeObserver:
  virtual void OnWindowActivated(aura::Window* gained_active,
                                 aura::Window* lost_active) OVERRIDE {
    if (window_ && lost_active == window_) {
      delete lost_active;
      did_delete_ = true;
    }
  }

  // Overridden from WindowDeleter:
  virtual aura::Window* GetDeletedWindow() OVERRIDE {
    return did_delete_ ? window_ : NULL;
  }

 private:
  aura::Window* root_;
  aura::Window* window_;
  bool did_delete_;

  DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseActivationChangeObserver);
};

// FocusChangeObserver that deletes the window losing focus.
class DeleteOnLoseFocusChangeObserver
    : public aura::client::FocusChangeObserver,
      public WindowDeleter {
 public:
  explicit DeleteOnLoseFocusChangeObserver(aura::Window* window)
      : root_(window->GetRootWindow()),
        window_(window),
        did_delete_(false) {
    aura::client::GetFocusClient(root_)->AddObserver(this);
  }
  virtual ~DeleteOnLoseFocusChangeObserver() {
    aura::client::GetFocusClient(root_)->RemoveObserver(this);
  }

  // Overridden from aura::client::FocusChangeObserver:
  virtual void OnWindowFocused(aura::Window* gained_focus,
                               aura::Window* lost_focus) OVERRIDE {
    if (window_ && lost_focus == window_) {
      delete lost_focus;
      did_delete_ = true;
    }
  }

  // Overridden from WindowDeleter:
  virtual aura::Window* GetDeletedWindow() OVERRIDE {
    return did_delete_ ? window_ : NULL;
  }

 private:
  aura::Window* root_;
  aura::Window* window_;
  bool did_delete_;

  DISALLOW_COPY_AND_ASSIGN(DeleteOnLoseFocusChangeObserver);
};

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 {
    wm_state_.reset(new wm::WMState);
    // 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();
    wm_state_.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_;
  scoped_ptr<wm::WMState> wm_state_;

  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);
  }

  // Verifies if a window that loses activation or focus 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());

    {
      aura::Window* to_delete = root_window()->GetChildById(1);
      DeleteOnLoseActivationChangeObserver observer1(to_delete);
      RecordingActivationAndFocusChangeObserver observer2(root_window(),
                                                          &observer1);

      FocusWindowById(2);

      EXPECT_EQ(2, GetActiveWindowId());
      EXPECT_EQ(2, GetFocusedWindowId());

      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
    }

    {
      aura::Window* to_delete = root_window()->GetChildById(2);
      DeleteOnLoseFocusChangeObserver observer1(to_delete);
      RecordingActivationAndFocusChangeObserver observer2(root_window(),
                                                          &observer1);

      FocusWindowById(3);

      EXPECT_EQ(3, GetActiveWindowId());
      EXPECT_EQ(3, GetFocusedWindowId());

      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
    }
  }

 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();
  }

 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 wm

/* [<][>][^][v][top][bottom][index][help] */