summaryrefslogtreecommitdiffstats
path: root/ui/views
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-27 22:36:12 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-27 22:36:12 +0000
commitf3196863b4bb76a8bb64c01ddf2ad5f71cd631d2 (patch)
tree53cfa578c4e2495de62ecee010fefd2ae2cbbf41 /ui/views
parente9613b5faae323d10b41d0693ea7be26cdc2de26 (diff)
downloadchromium_src-f3196863b4bb76a8bb64c01ddf2ad5f71cd631d2.zip
chromium_src-f3196863b4bb76a8bb64c01ddf2ad5f71cd631d2.tar.gz
chromium_src-f3196863b4bb76a8bb64c01ddf2ad5f71cd631d2.tar.bz2
More tests for FocusController:
. adds tests for focus and activation restrictions imposed by a custom FocusRules implementation. . tests Deactivate() . focus switching within the active window, and focus to a child window of an inactive activatable window. . setting focus or activation to the same window repeatedly should not send more events. Better macros for finer tuned control of test usage. Behavioral changes: . focus now activates the focusable window's activatable window. . activating a window now sets focus to the activatable window's focusable window. . focusing or activating a window multiple times does not send multiple events. . consolidate some code in FocusController making FocusWindow() the canonical implementation of focus/activation. http://crbug.com/162100 R=sky@chromium.org Review URL: https://codereview.chromium.org/11316196 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@169778 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views')
-rw-r--r--ui/views/corewm/focus_controller.cc24
-rw-r--r--ui/views/corewm/focus_controller_unittest.cc303
2 files changed, 282 insertions, 45 deletions
diff --git a/ui/views/corewm/focus_controller.cc b/ui/views/corewm/focus_controller.cc
index 62527e5..705530e 100644
--- a/ui/views/corewm/focus_controller.cc
+++ b/ui/views/corewm/focus_controller.cc
@@ -58,7 +58,12 @@ FocusController::~FocusController() {
}
void FocusController::FocusWindow(aura::Window* window) {
- SetFocusedWindow(window);
+ // Focusing a window also activates its containing activatable window. Note
+ // that the rules could redirect activation activation and/or focus.
+ aura::Window* focusable = rules_->GetFocusableWindow(window);
+ SetActiveWindow(rules_->GetActivatableWindow(focusable));
+ DCHECK(GetActiveWindow()->Contains(focusable));
+ SetFocusedWindow(focusable);
}
////////////////////////////////////////////////////////////////////////////////
@@ -75,11 +80,11 @@ void FocusController::RemoveObserver(
}
void FocusController::ActivateWindow(aura::Window* window) {
- SetActiveWindow(rules_->GetActivatableWindow(window));
+ FocusWindow(window);
}
void FocusController::DeactivateWindow(aura::Window* window) {
- SetActiveWindow(rules_->GetNextActivatableWindow(window));
+ FocusWindow(rules_->GetNextActivatableWindow(window));
}
aura::Window* FocusController::GetActiveWindow() {
@@ -163,6 +168,8 @@ bool FocusController::CanDispatchToTarget(ui::EventTarget* target) {
// FocusController, private:
void FocusController::SetFocusedWindow(aura::Window* window) {
+ if (window == focused_window_)
+ return;
DCHECK(rules_->CanFocusWindow(window));
if (window)
DCHECK_EQ(window, rules_->GetFocusableWindow(window));
@@ -176,6 +183,8 @@ void FocusController::SetFocusedWindow(aura::Window* window) {
}
void FocusController::SetActiveWindow(aura::Window* window) {
+ if (window == active_window_)
+ return;
DCHECK(rules_->CanActivateWindow(window));
if (window)
DCHECK_EQ(window, rules_->GetActivatableWindow(window));
@@ -190,6 +199,8 @@ void FocusController::SetActiveWindow(aura::Window* window) {
void FocusController::WindowLostFocusFromDispositionChange(
aura::Window* window) {
+ // TODO(beng): See if this function can be replaced by a call to
+ // FocusWindow().
// Activation adjustments are handled first in the event of a disposition
// changed. If an activation change is necessary, focus is reset as part of
// that process so there's no point in updating focus independently.
@@ -204,12 +215,7 @@ void FocusController::WindowLostFocusFromDispositionChange(
}
void FocusController::WindowFocusedFromInputEvent(aura::Window* window) {
- aura::Window* activatable = rules_->GetActivatableWindow(window);
- SetActiveWindow(activatable);
-
- // This handles switching focus via input events within the active window.
- SetFocusedWindow(rules_->GetFocusableWindow(
- activatable->Contains(window) ? window : activatable));
+ FocusWindow(window);
}
} // namespace corewm
diff --git a/ui/views/corewm/focus_controller_unittest.cc b/ui/views/corewm/focus_controller_unittest.cc
index 90464cb..2d0ca22 100644
--- a/ui/views/corewm/focus_controller_unittest.cc
+++ b/ui/views/corewm/focus_controller_unittest.cc
@@ -68,6 +68,63 @@ class FocusEventsTestHandler : public ui::EventHandler,
DISALLOW_COPY_AND_ASSIGN(FocusEventsTestHandler);
};
+// 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 CanActivateWindow(aura::Window* window) 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(GetActivatableWindow(focus_restriction_));
+ return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
+ }
+ virtual bool CanFocusWindow(aura::Window* window) OVERRIDE {
+ return CanFocusOrActivate(window) ?
+ BaseFocusRules::CanFocusWindow(window) : false;
+ }
+ virtual aura::Window* GetActivatableWindow(aura::Window* window) OVERRIDE {
+ return BaseFocusRules::GetActivatableWindow(
+ CanFocusOrActivate(window) ? window : focus_restriction_);
+ }
+ virtual aura::Window* GetFocusableWindow(aura::Window* window) OVERRIDE {
+ return BaseFocusRules::GetFocusableWindow(
+ CanFocusOrActivate(window) ? window : focus_restriction_);
+ }
+ virtual aura::Window* GetNextActivatableWindow(
+ aura::Window* ignore) OVERRIDE {
+ aura::Window* next_activatable =
+ BaseFocusRules::GetNextActivatableWindow(ignore);
+ return CanFocusOrActivate(next_activatable) ?
+ next_activatable : GetActivatableWindow(focus_restriction_);
+ }
+ virtual aura::Window* GetNextFocusableWindow(aura::Window* ignore) OVERRIDE {
+ aura::Window* next_focusable =
+ BaseFocusRules::GetNextFocusableWindow(ignore);
+ return CanFocusOrActivate(next_focusable) ?
+ next_focusable : 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:
@@ -78,7 +135,8 @@ class FocusControllerTestBase : public aura::test::AuraTestBase {
// 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.
- focus_controller_.reset(new FocusController(new BaseFocusRules));
+ test_focus_rules_ = new TestFocusRules;
+ focus_controller_.reset(new FocusController(test_focus_rules_));
aura::test::AuraTestBase::SetUp();
root_window()->AddPreTargetHandler(focus_controller());
aura::client::SetActivationClient(root_window(), focus_controller());
@@ -86,16 +144,21 @@ class FocusControllerTestBase : public aura::test::AuraTestBase {
// Hierarchy used by all tests:
// root_window
// +-- w1
- // +-- w11
+ // | +-- w11
+ // | +-- w12
// +-- w2
- // +-- w21
- // +-- w211
+ // | +-- w21
+ // | +-- w211
+ // +-- w3
aura::Window* w1 = aura::test::CreateTestWindowWithDelegate(
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1,
gfx::Rect(0, 0, 50, 50), NULL);
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), NULL);
@@ -105,10 +168,14 @@ class FocusControllerTestBase : public aura::test::AuraTestBase {
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), NULL);
}
virtual void TearDown() OVERRIDE {
root_window()->RemovePreTargetHandler(focus_controller());
aura::test::AuraTestBase::TearDown();
+ test_focus_rules_ = NULL; // Owned by FocusController.
focus_controller_.reset();
}
@@ -121,6 +188,9 @@ class FocusControllerTestBase : public aura::test::AuraTestBase {
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();
}
@@ -140,14 +210,23 @@ class FocusControllerTestBase : public aura::test::AuraTestBase {
FocusChangeEvent::activation_changed_event_type()));
}
+ 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 DuplicateActivationEvents() {}
+ virtual void ShiftFocusWithinActiveWindow() {}
+ virtual void ShiftFocusToChildOfInactiveWindow() {}
+ virtual void FocusRulesOverride() = 0;
+ virtual void ActivationRulesOverride() = 0;
private:
scoped_ptr<FocusController> focus_controller_;
+ TestFocusRules* test_focus_rules_;
DISALLOW_COPY_AND_ASSIGN(FocusControllerTestBase);
};
@@ -160,6 +239,7 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase {
// 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;
void FocusWindowById(int id) {
aura::Window* window = root_window()->GetChildById(id);
@@ -186,6 +266,8 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase {
EXPECT_EQ(1, GetActiveWindowId());
ActivateWindowById(2);
EXPECT_EQ(2, GetActiveWindowId());
+ DeactivateWindow(GetActiveWindow());
+ EXPECT_EQ(3, GetActiveWindowId());
}
virtual void FocusEvents() OVERRIDE {
FocusEventsTestHandler handler(root_window()->GetChildById(1));
@@ -199,7 +281,24 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase {
EXPECT_EQ(1, handler.GetCountForEventType(
FocusChangeEvent::focus_changed_event_type()));
}
-
+ virtual void DuplicateFocusEvents() OVERRIDE {
+ // Focusing an existing focused window should not resend focus events.
+ FocusEventsTestHandler handler(root_window());
+ EXPECT_EQ(0, handler.GetCountForEventType(
+ FocusChangeEvent::focus_changing_event_type()));
+ EXPECT_EQ(0, handler.GetCountForEventType(
+ FocusChangeEvent::focus_changed_event_type()));
+ FocusWindowById(1);
+ EXPECT_EQ(1, handler.GetCountForEventType(
+ FocusChangeEvent::focus_changing_event_type()));
+ EXPECT_EQ(1, handler.GetCountForEventType(
+ FocusChangeEvent::focus_changed_event_type()));
+ FocusWindowById(1);
+ EXPECT_EQ(1, handler.GetCountForEventType(
+ FocusChangeEvent::focus_changing_event_type()));
+ EXPECT_EQ(1, handler.GetCountForEventType(
+ FocusChangeEvent::focus_changed_event_type()));
+ }
virtual void ActivationEvents() OVERRIDE {
ActivateWindowById(1);
@@ -215,6 +314,65 @@ class FocusControllerDirectTestBase : public FocusControllerTestBase {
ExpectActivationEvents(&handler_1, 1, 0);
ExpectActivationEvents(&handler_2, 0, 1);
}
+ virtual void DuplicateActivationEvents() OVERRIDE {
+ // Activating an existing active window should not resend activation events.
+ ActivateWindowById(1);
+
+ FocusEventsTestHandler handler_root(root_window());
+ ExpectActivationEvents(&handler_root, 0, 0);
+ ActivateWindowById(2);
+ ExpectActivationEvents(&handler_root, 1, 1);
+ ActivateWindowById(2);
+ ExpectActivationEvents(&handler_root, 1, 1);
+ }
+ virtual void ShiftFocusWithinActiveWindow() OVERRIDE {
+ ActivateWindowById(1);
+ EXPECT_EQ(1, GetActiveWindowId());
+ EXPECT_EQ(1, focused_window_id());
+ FocusWindowById(11);
+ EXPECT_EQ(11, focused_window_id());
+ FocusWindowById(12);
+ EXPECT_EQ(12, focused_window_id());
+ }
+ virtual void ShiftFocusToChildOfInactiveWindow() OVERRIDE {
+ ActivateWindowById(2);
+ EXPECT_EQ(2, GetActiveWindowId());
+ EXPECT_EQ(2, focused_window_id());
+ FocusWindowById(11);
+ EXPECT_EQ(1, GetActiveWindowId());
+ EXPECT_EQ(11, focused_window_id());
+ }
+ virtual void FocusRulesOverride() OVERRIDE {
+ EXPECT_EQ(NULL, focused_window());
+ FocusWindowById(11);
+ EXPECT_EQ(11, focused_window_id());
+
+ test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
+ FocusWindowById(12);
+ EXPECT_EQ(211, focused_window_id());
+
+ test_focus_rules()->set_focus_restriction(NULL);
+ FocusWindowById(12);
+ EXPECT_EQ(12, focused_window_id());
+ }
+ virtual void ActivationRulesOverride() OVERRIDE {
+ ActivateWindowById(1);
+ EXPECT_EQ(1, GetActiveWindowId());
+ EXPECT_EQ(1, focused_window_id());
+
+ aura::Window* w3 = root_window()->GetChildById(3);
+ test_focus_rules()->set_focus_restriction(w3);
+
+ ActivateWindowById(2);
+ // FocusRules restricts focus and activation to 3.
+ EXPECT_EQ(3, GetActiveWindowId());
+ EXPECT_EQ(3, focused_window_id());
+
+ test_focus_rules()->set_focus_restriction(NULL);
+ ActivateWindowById(2);
+ EXPECT_EQ(2, GetActiveWindowId());
+ EXPECT_EQ(2, focused_window_id());
+ }
private:
DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase);
@@ -233,6 +391,9 @@ class FocusControllerApiTest : public FocusControllerDirectTestBase {
virtual void ActivateWindowDirect(aura::Window* window) OVERRIDE {
ActivateWindow(window);
}
+ virtual void DeactivateWindowDirect(aura::Window* window) OVERRIDE {
+ DeactivateWindow(window);
+ }
DISALLOW_COPY_AND_ASSIGN(FocusControllerApiTest);
};
@@ -252,6 +413,12 @@ class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
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();
+ }
DISALLOW_COPY_AND_ASSIGN(FocusControllerMouseEventTest);
};
@@ -270,6 +437,12 @@ class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
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());
+ }
DISALLOW_COPY_AND_ASSIGN(FocusControllerGestureEventTest);
};
@@ -310,7 +483,7 @@ class FocusControllerImplicitTestBase : public FocusControllerTestBase {
EXPECT_EQ(2, GetActiveWindowId());
ChangeWindowDisposition(w2);
- EXPECT_EQ(1, GetActiveWindowId());
+ EXPECT_EQ(3, GetActiveWindowId());
}
virtual void FocusEvents() OVERRIDE {
aura::Window* w211 = root_window()->GetChildById(211);
@@ -334,17 +507,54 @@ class FocusControllerImplicitTestBase : public FocusControllerTestBase {
ActivateWindow(w2);
FocusEventsTestHandler handler_root(root_window());
- FocusEventsTestHandler handler_1(root_window()->GetChildById(1));
FocusEventsTestHandler handler_2(root_window()->GetChildById(2));
+ FocusEventsTestHandler handler_3(root_window()->GetChildById(3));
ExpectActivationEvents(&handler_root, 0, 0);
- ExpectActivationEvents(&handler_1, 0, 0);
ExpectActivationEvents(&handler_2, 0, 0);
+ ExpectActivationEvents(&handler_3, 0, 0);
ChangeWindowDisposition(w2);
ExpectActivationEvents(&handler_root, 1, 1);
- ExpectActivationEvents(&handler_1, 0, 1);
ExpectActivationEvents(&handler_2, 1, 0);
+ ExpectActivationEvents(&handler_3, 0, 1);
+ }
+ virtual void FocusRulesOverride() OVERRIDE {
+ EXPECT_EQ(NULL, focused_window());
+ aura::Window* w211 = root_window()->GetChildById(211);
+ focus_controller()->FocusWindow(w211);
+ EXPECT_EQ(211, focused_window_id());
+
+ 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, focused_window_id());
+
+ 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, focused_window_id());
+
+ 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, focused_window_id());
+
+ test_focus_rules()->set_focus_restriction(NULL);
+ ActivateWindow(root_window()->GetChildById(2));
+ EXPECT_EQ(2, GetActiveWindowId());
+ EXPECT_EQ(2, focused_window_id());
}
private:
@@ -452,52 +662,73 @@ class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }
-#define FOCUS_TESTS(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) \
+ 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(FocusControllerParentHideTest, 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) \
+ FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)
-// Activation tests do not have Parent* variants as that is not a supported
-// event flow.
-#define ACTIVATION_TESTS(TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
- FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, 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.
-FOCUS_TESTS(BasicFocus);
+ALL_FOCUS_TESTS(BasicFocus);
// - Activates a window, verifies that activation changed.
-ACTIVATION_TESTS(BasicActivation);
+TARGET_FOCUS_TESTS(BasicActivation);
// - Focuses a window, verifies that focus events were dispatched.
-FOCUS_TESTS(FocusEvents);
+ALL_FOCUS_TESTS(FocusEvents);
-// - Activates a window, verifies that activation events were dispatched.
-ACTIVATION_TESTS(ActivationEvents);
+// - 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);
-// - Focuses a window, re-targets event prior to -ed event being dispatched.
-TEST_F(FocusControllerApiTest, RetargetFocusEvent) {
+// - Activates a window, verifies that activation events were dispatched.
+TARGET_FOCUS_TESTS(ActivationEvents);
-}
+// - Input events/API calls shift focus between focusable windows within the
+// active window.
+DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow);
-// - Activates a window, re-targets event prior to -ed event being dispatched.
-TEST_F(FocusControllerApiTest, RetargetActivationEvent) {
+// - 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);
-}
+// - Verifies that FocusRules determine what can be focused.
+ALL_FOCUS_TESTS(FocusRulesOverride);
-// TODO(beng):
-// . window->window focus changes within an active window
-// . focus and activation changes within a single test.
+// - Verifies that FocusRules determine what can be activated.
+TARGET_FOCUS_TESTS(ActivationRulesOverride);
} // namespace corewm
} // namespace views