#include "ui/wm/core/focus_controller.h"
#include <map>
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.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/test/aura_test_base.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/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
#include "ui/events/test/event_generator.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_change_observer.h"
#include "ui/wm/public/activation_client.h"
#if DCHECK_IS_ON()
#define EXPECT_DCHECK(statement, regex) \
EXPECT_DEATH_IF_SUPPORTED(statement, regex)
#else
#define EXPECT_DCHECK(statement, regex) \
{ statement; }
#endif
namespace wm {
class FocusNotificationObserver : public ActivationChangeObserver,
public aura::client::FocusChangeObserver {
public:
FocusNotificationObserver()
: last_activation_reason_(ActivationReason::ACTIVATION_CLIENT),
activation_changed_count_(0),
focus_changed_count_(0),
reactivation_count_(0),
reactivation_requested_window_(nullptr),
reactivation_actual_window_(nullptr) {}
FocusNotificationObserver(const FocusNotificationObserver&) = delete;
FocusNotificationObserver& operator=(const FocusNotificationObserver&) =
delete;
~FocusNotificationObserver() override {}
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_);
}
ActivationReason last_activation_reason() const {
return last_activation_reason_;
}
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:
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override {
last_activation_reason_ = reason;
++activation_changed_count_;
}
void OnAttemptToReactivateWindow(aura::Window* request_active,
aura::Window* actual_active) override {
++reactivation_count_;
reactivation_requested_window_ = request_active;
reactivation_actual_window_ = actual_active;
}
void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override {
++focus_changed_count_;
}
ActivationReason last_activation_reason_;
int activation_changed_count_;
int focus_changed_count_;
int reactivation_count_;
raw_ptr<aura::Window> reactivation_requested_window_;
raw_ptr<aura::Window> reactivation_actual_window_;
};
class WindowDeleter {
public:
virtual aura::Window* GetDeletedWindow() = 0;
protected:
virtual ~WindowDeleter() {}
};
class RecordingActivationAndFocusChangeObserver
: public ActivationChangeObserver,
public aura::client::FocusChangeObserver {
public:
RecordingActivationAndFocusChangeObserver(aura::Window* root,
WindowDeleter* deleter)
: root_(root),
deleter_(deleter),
was_notified_with_deleted_window_(false) {
GetActivationClient(root_)->AddObserver(this);
aura::client::GetFocusClient(root_)->AddObserver(this);
}
RecordingActivationAndFocusChangeObserver(
const RecordingActivationAndFocusChangeObserver&) = delete;
RecordingActivationAndFocusChangeObserver& operator=(
const RecordingActivationAndFocusChangeObserver&) = delete;
~RecordingActivationAndFocusChangeObserver() override {
GetActivationClient(root_)->RemoveObserver(this);
aura::client::GetFocusClient(root_)->RemoveObserver(this);
}
bool was_notified_with_deleted_window() const {
return was_notified_with_deleted_window_;
}
void OnWindowActivating(ActivationReason reason,
aura::Window* gaining_active,
aura::Window* losing_active) override {
if (deleter_->GetDeletedWindow()) {
auto* active_window = GetActivationClient(root_)->GetActiveWindow();
EXPECT_NE(active_window, deleter_->GetDeletedWindow());
EXPECT_NE(gaining_active, deleter_->GetDeletedWindow());
EXPECT_NE(losing_active, deleter_->GetDeletedWindow());
}
}
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override {
if (lost_active && lost_active == deleter_->GetDeletedWindow())
was_notified_with_deleted_window_ = true;
}
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:
raw_ptr<aura::Window> root_;
raw_ptr<WindowDeleter> deleter_;
bool was_notified_with_deleted_window_;
};
class HideOnLoseActivationChangeObserver : public ActivationChangeObserver {
public:
explicit HideOnLoseActivationChangeObserver(aura::Window* window_to_hide)
: root_(window_to_hide->GetRootWindow()),
window_to_hide_(window_to_hide) {
GetActivationClient(root_)->AddObserver(this);
}
HideOnLoseActivationChangeObserver(
const HideOnLoseActivationChangeObserver&) = delete;
HideOnLoseActivationChangeObserver& operator=(
const HideOnLoseActivationChangeObserver&) = delete;
~HideOnLoseActivationChangeObserver() override {
GetActivationClient(root_)->RemoveObserver(this);
}
aura::Window* window_to_hide() { return window_to_hide_; }
private:
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override {
if (window_to_hide_) {
aura::Window* window_to_hide = window_to_hide_;
window_to_hide_ = nullptr;
window_to_hide->Hide();
}
}
raw_ptr<aura::Window> root_;
raw_ptr<aura::Window> window_to_hide_;
};
class DeleteOnActivationChangeObserver : public ActivationChangeObserver,
public WindowDeleter {
public:
DeleteOnActivationChangeObserver(aura::Window* window,
bool delete_on_activating,
bool delete_window_losing_active)
: root_(window->GetRootWindow()),
window_(window),
delete_on_activating_(delete_on_activating),
delete_window_losing_active_(delete_window_losing_active),
did_delete_(false) {
GetActivationClient(root_)->AddObserver(this);
}
DeleteOnActivationChangeObserver(const DeleteOnActivationChangeObserver&) =
delete;
DeleteOnActivationChangeObserver& operator=(
const DeleteOnActivationChangeObserver&) = delete;
~DeleteOnActivationChangeObserver() override {
GetActivationClient(root_)->RemoveObserver(this);
}
void OnWindowActivating(ActivationReason reason,
aura::Window* gaining_active,
aura::Window* losing_active) override {
if (!delete_on_activating_)
return;
auto* window_to_delete =
delete_window_losing_active_ ? losing_active : gaining_active;
if (window_ && window_to_delete == window_) {
delete window_to_delete;
did_delete_ = true;
}
}
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override {
if (delete_on_activating_)
return;
auto* window_to_delete =
delete_window_losing_active_ ? lost_active : gained_active;
if (window_ && window_to_delete == window_) {
delete window_to_delete;
did_delete_ = true;
}
}
aura::Window* GetDeletedWindow() override {
return did_delete_ ? window_.get() : nullptr;
}
private:
raw_ptr<aura::Window> root_;
raw_ptr<aura::Window, DanglingUntriaged> window_;
const bool delete_on_activating_;
const bool delete_window_losing_active_;
bool did_delete_;
};
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);
}
DeleteOnLoseFocusChangeObserver(const DeleteOnLoseFocusChangeObserver&) =
delete;
DeleteOnLoseFocusChangeObserver& operator=(
const DeleteOnLoseFocusChangeObserver&) = delete;
~DeleteOnLoseFocusChangeObserver() override {
aura::client::GetFocusClient(root_)->RemoveObserver(this);
}
void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override {
if (window_ && lost_focus == window_) {
delete lost_focus;
did_delete_ = true;
}
}
aura::Window* GetDeletedWindow() override {
return did_delete_ ? window_.get() : nullptr;
}
private:
raw_ptr<aura::Window> root_;
raw_ptr<aura::Window, DanglingUntriaged> window_;
bool did_delete_;
};
class ScopedFocusNotificationObserver : public FocusNotificationObserver {
public:
ScopedFocusNotificationObserver(aura::Window* root_window)
: root_window_(root_window) {
GetActivationClient(root_window_)->AddObserver(this);
aura::client::GetFocusClient(root_window_)->AddObserver(this);
}
ScopedFocusNotificationObserver(const ScopedFocusNotificationObserver&) =
delete;
ScopedFocusNotificationObserver& operator=(
const ScopedFocusNotificationObserver&) = delete;
~ScopedFocusNotificationObserver() override {
GetActivationClient(root_window_)->RemoveObserver(this);
aura::client::GetFocusClient(root_window_)->RemoveObserver(this);
}
private:
raw_ptr<aura::Window> root_window_;
};
class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver {
public:
ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id)
: target_(root_window->GetChildById(id)) {
SetActivationChangeObserver(target_, this);
aura::client::SetFocusChangeObserver(target_, this);
tracker_.Add(target_);
}
ScopedTargetFocusNotificationObserver(
const ScopedTargetFocusNotificationObserver&) = delete;
ScopedTargetFocusNotificationObserver& operator=(
const ScopedTargetFocusNotificationObserver&) = delete;
~ScopedTargetFocusNotificationObserver() override {
if (tracker_.Contains(target_)) {
SetActivationChangeObserver(target_, nullptr);
aura::client::SetFocusChangeObserver(target_, nullptr);
}
}
private:
raw_ptr<aura::Window, DanglingUntriaged> target_;
aura::WindowTracker tracker_;
};
class SimpleEventHandler : public ui::EventHandler {
public:
SimpleEventHandler() {}
SimpleEventHandler(const SimpleEventHandler&) = delete;
SimpleEventHandler& operator=(const SimpleEventHandler&) = delete;
~SimpleEventHandler() override {}
void OnMouseEvent(ui::MouseEvent* event) override { event->SetHandled(); }
void OnGestureEvent(ui::GestureEvent* event) override { event->SetHandled(); }
};
class FocusShiftingActivationObserver : public ActivationChangeObserver {
public:
explicit FocusShiftingActivationObserver(aura::Window* activated_window)
: activated_window_(activated_window), shift_focus_to_(nullptr) {}
FocusShiftingActivationObserver(const FocusShiftingActivationObserver&) =
delete;
FocusShiftingActivationObserver& operator=(
const FocusShiftingActivationObserver&) = delete;
~FocusShiftingActivationObserver() override {}
void set_shift_focus_to(aura::Window* shift_focus_to) {
shift_focus_to_ = shift_focus_to;
}
private:
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override {
if (gained_active == activated_window_) {
aura::client::FocusClient* client =
aura::client::GetFocusClient(gained_active);
client->FocusWindow(shift_focus_to_);
}
}
raw_ptr<aura::Window> activated_window_;
raw_ptr<aura::Window> shift_focus_to_;
};
class ActivateWhileActivatingObserver : public ActivationChangeObserver {
public:
ActivateWhileActivatingObserver(aura::Window* to_observe,
aura::Window* to_activate,
aura::Window* to_focus)
: to_observe_(to_observe),
to_activate_(to_activate),
to_focus_(to_focus) {
GetActivationClient(to_observe_->GetRootWindow())->AddObserver(this);
}
ActivateWhileActivatingObserver(const ActivateWhileActivatingObserver&) =
delete;
ActivateWhileActivatingObserver& operator=(
const ActivateWhileActivatingObserver&) = delete;
~ActivateWhileActivatingObserver() override {
GetActivationClient(to_observe_->GetRootWindow())->RemoveObserver(this);
}
private:
void OnWindowActivating(ActivationReason reason,
aura::Window* gaining_active,
aura::Window* losing_active) override {
if (gaining_active != to_observe_)
return;
if (to_activate_)
ActivateWindow(to_activate_);
if (to_focus_)
FocusWindow(to_focus_);
}
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override {}
void ActivateWindow(aura::Window* window) {
GetActivationClient(to_observe_->GetRootWindow())->ActivateWindow(window);
}
void FocusWindow(aura::Window* window) {
aura::client::GetFocusClient(to_observe_->GetRootWindow())
->FocusWindow(window);
}
raw_ptr<aura::Window> to_observe_;
raw_ptr<aura::Window> to_activate_;
raw_ptr<aura::Window> to_focus_;
};
class TestFocusRules : public BaseFocusRules {
public:
TestFocusRules() : focus_restriction_(nullptr) {}
TestFocusRules(const TestFocusRules&) = delete;
TestFocusRules& operator=(const TestFocusRules&) = delete;
void set_focus_restriction(aura::Window* focus_restriction) {
focus_restriction_ = focus_restriction;
}
bool SupportsChildActivation(const aura::Window* window) const override {
return window->GetRootWindow() == window;
}
bool CanActivateWindow(const aura::Window* window) const override {
bool can_activate =
CanFocusOrActivate(window) || window->Contains(focus_restriction_);
return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
}
bool CanFocusWindow(const aura::Window* window,
const ui::Event* event) const override {
return CanFocusOrActivate(window)
? BaseFocusRules::CanFocusWindow(window, event)
: false;
}
aura::Window* GetActivatableWindow(aura::Window* window) const override {
return BaseFocusRules::GetActivatableWindow(
CanFocusOrActivate(window) ? window : focus_restriction_.get());
}
aura::Window* GetFocusableWindow(aura::Window* window) const override {
return BaseFocusRules::GetFocusableWindow(
CanFocusOrActivate(window) ? window : focus_restriction_.get());
}
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(const aura::Window* window) const {
return !focus_restriction_ || focus_restriction_->Contains(window);
}
raw_ptr<aura::Window> focus_restriction_;
};
class FocusControllerTestBase : public aura::test::AuraTestBase {
public:
FocusControllerTestBase(const FocusControllerTestBase&) = delete;
FocusControllerTestBase& operator=(const FocusControllerTestBase&) = delete;
protected:
FocusControllerTestBase() {}
void SetUp() override {
test_focus_rules_ = new TestFocusRules;
focus_controller_ = std::make_unique<FocusController>(test_focus_rules_);
aura::test::AuraTestBase::SetUp();
root_window()->AddPreTargetHandler(focus_controller_.get());
aura::client::SetFocusClient(root_window(), focus_controller_.get());
SetActivationClient(root_window(), focus_controller_.get());
aura::Window* w1 =
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = root_window(),
.bounds = {50, 50},
.window_id = 1})
.release();
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = w1,
.bounds = {5, 5, 10, 10},
.window_id = 11})
.release();
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = w1,
.bounds = {15, 15, 10, 10},
.window_id = 12})
.release();
aura::Window* w2 =
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = root_window(),
.bounds = {75, 75, 50, 50},
.window_id = 2})
.release();
aura::Window* w21 =
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = w2,
.bounds = {5, 5, 10, 10},
.window_id = 21})
.release();
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = w21,
.bounds = {1, 1, 5, 5},
.window_id = 211})
.release();
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = root_window(),
.bounds = {125, 125, 50, 50},
.window_id = 3})
.release();
}
void TearDown() override {
root_window()->RemovePreTargetHandler(focus_controller_.get());
aura::test::AuraTestBase::TearDown();
test_focus_rules_ = nullptr;
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->GetId() : -1;
}
void ActivateWindow(aura::Window* window) {
GetActivationClient(root_window())->ActivateWindow(window);
}
void DeactivateWindow(aura::Window* window) {
GetActivationClient(root_window())->DeactivateWindow(window);
}
aura::Window* GetActiveWindow() {
return GetActivationClient(root_window())->GetActiveWindow();
}
int GetActiveWindowId() {
aura::Window* active_window = GetActiveWindow();
return active_window ? active_window->GetId() : -1;
}
TestFocusRules* test_focus_rules() { return test_focus_rules_; }
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 FocusChangeDuringDrag() {}
virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
virtual void DontPassDeletedWindow() {}
virtual void StackWindowAtTopOnActivation() {}
virtual void HideFocusedWindowDuringActivationLoss() {}
virtual void ActivateWhileActivating() {}
private:
std::unique_ptr<FocusController> focus_controller_;
raw_ptr<TestFocusRules> test_focus_rules_;
};
class FocusControllerDirectTestBase : public FocusControllerTestBase {
public:
FocusControllerDirectTestBase(const FocusControllerDirectTestBase&) = delete;
FocusControllerDirectTestBase& operator=(
const FocusControllerDirectTestBase&) = delete;
protected:
FocusControllerDirectTestBase() {}
virtual void FocusWindowDirect(aura::Window* window) = 0;
virtual void ActivateWindowDirect(aura::Window* window) = 0;
virtual void DeactivateWindowDirect(aura::Window* window) = 0;
virtual bool IsInputEvent() = 0;
virtual ActivationChangeObserver::ActivationReason
GetExpectedActivationReason() const = 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);
}
void DeactivateWindowById(int id) {
aura::Window* window = root_window()->GetChildById(id);
EXPECT_TRUE(window);
GetActivationClient(root_window())->DeactivateWindow(window);
}
void BasicFocus() override {
EXPECT_FALSE(GetFocusedWindow());
FocusWindowById(1);
EXPECT_EQ(1, GetFocusedWindowId());
FocusWindowById(2);
EXPECT_EQ(2, GetFocusedWindowId());
}
void BasicActivation() override {
EXPECT_FALSE(GetActiveWindow());
ActivateWindowById(1);
EXPECT_EQ(1, GetActiveWindowId());
ActivateWindowById(2);
EXPECT_EQ(2, GetActiveWindowId());
aura::Window* window3 = root_window()->GetChildById(3);
root_window()->StackChildAtTop(window3);
DeactivateWindowById(1);
EXPECT_EQ(2, GetActiveWindowId());
DeactivateWindow(nullptr);
EXPECT_EQ(2, GetActiveWindowId());
DeactivateWindow(GetActiveWindow());
EXPECT_EQ(3, GetActiveWindowId());
}
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);
}
void DuplicateFocusEvents() override {
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);
}
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);
EXPECT_EQ(GetExpectedActivationReason(),
root_observer.last_activation_reason());
observer1.ExpectCounts(1, 1);
observer2.ExpectCounts(1, 1);
}
void ReactivationEvents() override {
ActivateWindowById(1);
ScopedFocusNotificationObserver root_observer(root_window());
EXPECT_EQ(0, root_observer.reactivation_count());
root_window()->GetChildById(2)->Hide();
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());
}
void DuplicateActivationEvents() 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);
ActivateWindowById(2);
root_observer.ExpectCounts(1, 1);
observer1.ExpectCounts(1, 1);
observer2.ExpectCounts(1, 1);
}
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());
}
void ShiftFocusToChildOfInactiveWindow() override {
ActivateWindowById(2);
EXPECT_EQ(2, GetActiveWindowId());
EXPECT_EQ(2, GetFocusedWindowId());
FocusWindowById(11);
EXPECT_EQ(1, GetActiveWindowId());
EXPECT_EQ(11, GetFocusedWindowId());
}
void ShiftFocusToParentOfFocusedWindow() override {
ActivateWindowById(1);
EXPECT_EQ(1, GetFocusedWindowId());
FocusWindowById(11);
EXPECT_EQ(11, GetFocusedWindowId());
FocusWindowById(1);
EXPECT_EQ(11, GetFocusedWindowId());
}
void FocusRulesOverride() override {
EXPECT_FALSE(GetFocusedWindow());
FocusWindowById(11);
EXPECT_EQ(11, GetFocusedWindowId());
test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
FocusWindowById(12);
int focused_window = IsInputEvent() ? 11 : 211;
EXPECT_EQ(focused_window, GetFocusedWindowId());
test_focus_rules()->set_focus_restriction(nullptr);
FocusWindowById(12);
EXPECT_EQ(12, GetFocusedWindowId());
}
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);
int active_window = IsInputEvent() ? 1 : 3;
EXPECT_EQ(active_window, GetActiveWindowId());
EXPECT_EQ(active_window, GetFocusedWindowId());
test_focus_rules()->set_focus_restriction(nullptr);
ActivateWindowById(2);
EXPECT_EQ(2, GetActiveWindowId());
EXPECT_EQ(2, GetFocusedWindowId());
}
void ShiftFocusOnActivation() override {
ActivateWindowById(2);
EXPECT_EQ(2, GetFocusedWindowId());
ActivateWindowById(1);
EXPECT_EQ(1, GetFocusedWindowId());
ActivateWindowById(2);
aura::Window* target = root_window()->GetChildById(1);
ActivationClient* client = GetActivationClient(root_window());
std::unique_ptr<FocusShiftingActivationObserver> observer(
new FocusShiftingActivationObserver(target));
observer->set_shift_focus_to(target->GetChildById(11));
client->AddObserver(observer.get());
ActivateWindowById(1);
EXPECT_EQ(11, GetFocusedWindowId());
ActivateWindowById(2);
EXPECT_EQ(2, GetFocusedWindowId());
observer->set_shift_focus_to(nullptr);
ActivateWindowById(1);
EXPECT_EQ(1, GetFocusedWindowId());
client->RemoveObserver(observer.get());
ActivateWindowById(2);
EXPECT_EQ(2, GetFocusedWindowId());
ActivateWindowById(1);
EXPECT_EQ(1, GetFocusedWindowId());
}
void ShiftFocusOnActivationDueToHide() override {
ActivateWindowById(1);
EXPECT_EQ(1, GetFocusedWindowId());
root_window()->GetChildById(3)->Hide();
EXPECT_EQ(1, GetFocusedWindowId());
aura::Window* target = root_window()->GetChildById(2);
ActivationClient* client = GetActivationClient(root_window());
std::unique_ptr<FocusShiftingActivationObserver> observer(
new FocusShiftingActivationObserver(target));
observer->set_shift_focus_to(target->GetChildById(21));
client->AddObserver(observer.get());
root_window()->GetChildById(1)->Hide();
EXPECT_EQ(21, GetFocusedWindowId());
client->RemoveObserver(observer.get());
}
void NoShiftActiveOnActivation() override {
}
void FocusChangeDuringDrag() override {
std::unique_ptr<aura::client::DefaultCaptureClient> capture_client(
new aura::client::DefaultCaptureClient(root_window()));
ActivateWindowById(1);
EXPECT_EQ(1, GetActiveWindowId());
EXPECT_EQ(1, GetFocusedWindowId());
aura::Window* w2 = root_window()->GetChildById(2);
ui::test::EventGenerator generator(root_window(), w2);
generator.PressLeftButton();
aura::client::GetCaptureClient(root_window())->SetCapture(w2);
EXPECT_EQ(2, GetActiveWindowId());
EXPECT_EQ(2, GetFocusedWindowId());
generator.MoveMouseTo(gfx::Point(0, 0));
aura::Window* w1 = root_window()->GetChildById(1);
aura::client::GetCaptureClient(root_window())->SetCapture(w1);
GetActivationClient(root_window())->ActivateWindow(w1);
EXPECT_EQ(1, GetActiveWindowId());
EXPECT_EQ(1, GetFocusedWindowId());
generator.ReleaseLeftButton();
aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
}
void ChangeFocusWhenNothingFocusedAndCaptured() override {
std::unique_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);
}
void DontPassDeletedWindow() override {
FocusWindowById(1);
EXPECT_EQ(1, GetActiveWindowId());
EXPECT_EQ(1, GetFocusedWindowId());
{
aura::Window* to_delete = root_window()->GetChildById(1);
DeleteOnActivationChangeObserver observer1(
to_delete,
true,
true);
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);
DeleteOnActivationChangeObserver observer1(
to_delete, false,
true);
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());
}
{
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = root_window(),
.bounds = {125, 125, 50, 50},
.window_id = 4})
.release();
EXPECT_EQ(3, GetActiveWindowId());
EXPECT_EQ(3, GetFocusedWindowId());
aura::Window* to_delete = root_window()->GetChildById(3);
DeleteOnLoseFocusChangeObserver observer1(to_delete);
RecordingActivationAndFocusChangeObserver observer2(root_window(),
&observer1);
FocusWindowById(4);
EXPECT_EQ(4, GetActiveWindowId());
EXPECT_EQ(4, GetFocusedWindowId());
EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
EXPECT_FALSE(observer2.was_notified_with_deleted_window());
}
{
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = root_window(),
.bounds = {125, 125, 50, 50},
.window_id = 5})
.release();
aura::test::CreateTestWindow(
{.delegate =
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
.parent = root_window(),
.bounds = {125, 125, 50, 50},
.window_id = 6})
.release();
EXPECT_EQ(4, GetActiveWindowId());
EXPECT_EQ(4, GetFocusedWindowId());
aura::Window* to_delete1 = root_window()->GetChildById(5);
DeleteOnActivationChangeObserver observer1(
to_delete1, false,
false);
RecordingActivationAndFocusChangeObserver observer2(root_window(),
&observer1);
aura::Window* to_delete2 = root_window()->GetChildById(6);
DeleteOnActivationChangeObserver observer3(
to_delete2, true,
false);
RecordingActivationAndFocusChangeObserver observer4(root_window(),
&observer3);
FocusWindowById(5);
EXPECT_EQ(4, GetActiveWindowId());
EXPECT_EQ(4, GetFocusedWindowId());
EXPECT_EQ(to_delete1, observer1.GetDeletedWindow());
EXPECT_FALSE(observer2.was_notified_with_deleted_window());
EXPECT_EQ(to_delete2, observer3.GetDeletedWindow());
EXPECT_FALSE(observer4.was_notified_with_deleted_window());
}
}
void StackWindowAtTopOnActivation() override {
std::unique_ptr<aura::Window> window1 =
std::make_unique<aura::Window>(nullptr);
window1->SetType(aura::client::WINDOW_TYPE_NORMAL);
window1->Init(ui::LAYER_TEXTURED);
root_window()->AddChild(window1.get());
window1->Show();
ActivateWindow(window1.get());
EXPECT_EQ(window1.get(), root_window()->children().back());
EXPECT_EQ(window1.get(), GetActiveWindow());
std::unique_ptr<aura::Window> window2 =
std::make_unique<aura::Window>(nullptr);
window2->SetType(aura::client::WINDOW_TYPE_NORMAL);
window2->Init(ui::LAYER_TEXTURED);
root_window()->AddChild(window2.get());
window2->Show();
EXPECT_EQ(window2.get(), root_window()->children().back());
EXPECT_EQ(window1.get(), GetActiveWindow());
ActivateWindow(window1.get());
EXPECT_EQ(window1.get(), root_window()->children().back());
EXPECT_EQ(window1.get(), GetActiveWindow());
}
void HideFocusedWindowDuringActivationLoss() override {
aura::Window* w11 = root_window()->GetChildById(11);
FocusWindow(w11);
EXPECT_EQ(11, GetFocusedWindowId());
EXPECT_EQ(1, GetActiveWindowId());
{
HideOnLoseActivationChangeObserver observer(w11);
ActivateWindowById(2);
EXPECT_EQ(nullptr, observer.window_to_hide());
EXPECT_EQ(2, GetActiveWindowId());
EXPECT_EQ(2, GetFocusedWindowId());
}
}
void ActivateWhileActivating() override {
aura::Window* w1 = root_window()->GetChildById(1);
aura::Window* w2 = root_window()->GetChildById(2);
ActivateWindowById(3);
{
ActivateWhileActivatingObserver observer(w1,
w1,
nullptr);
ActivateWindow(w1);
EXPECT_EQ(1, GetActiveWindowId());
}
ActivateWindowById(3);
{
ActivateWhileActivatingObserver observer(w1,
nullptr,
w1);
ActivateWindow(w1);
EXPECT_EQ(1, GetActiveWindowId());
EXPECT_EQ(1, GetFocusedWindowId());
}
ActivateWindowById(3);
{
aura::Window* w11 = root_window()->GetChildById(11);
aura::Window* w12 = root_window()->GetChildById(12);
ActivateWhileActivatingObserver observer(w1,
nullptr,
w12);
FocusWindow(w11);
EXPECT_EQ(1, GetActiveWindowId());
EXPECT_EQ(12, GetFocusedWindowId());
}
ActivateWindowById(3);
{
ActivateWhileActivatingObserver observer(w2,
w1,
nullptr);
EXPECT_DCHECK(
{
ActivateWindow(w2);
EXPECT_EQ(2, GetActiveWindowId());
},
"");
}
}
};
class FocusControllerApiTest : public FocusControllerDirectTestBase {
public:
FocusControllerApiTest() {}
FocusControllerApiTest(const FocusControllerApiTest&) = delete;
FocusControllerApiTest& operator=(const FocusControllerApiTest&) = delete;
private:
void FocusWindowDirect(aura::Window* window) override { FocusWindow(window); }
void ActivateWindowDirect(aura::Window* window) override {
ActivateWindow(window);
}
void DeactivateWindowDirect(aura::Window* window) override {
DeactivateWindow(window);
}
bool IsInputEvent() override { return false; }
ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
const override {
return ActivationChangeObserver::ActivationReason::ACTIVATION_CLIENT;
}
};
class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
public:
FocusControllerMouseEventTest() {}
FocusControllerMouseEventTest(const FocusControllerMouseEventTest&) = delete;
FocusControllerMouseEventTest& operator=(
const FocusControllerMouseEventTest&) = delete;
void IgnoreHandledEvent() {
EXPECT_FALSE(GetActiveWindow());
aura::Window* w1 = root_window()->GetChildById(1);
SimpleEventHandler handler;
root_window()->AddPreTargetHandler(&handler,
ui::EventTarget::Priority::kSystem);
ui::test::EventGenerator generator(root_window(), w1);
generator.ClickLeftButton();
EXPECT_FALSE(GetActiveWindow());
generator.GestureTapAt(w1->bounds().CenterPoint());
EXPECT_FALSE(GetActiveWindow());
root_window()->RemovePreTargetHandler(&handler);
generator.ClickLeftButton();
EXPECT_EQ(1, GetActiveWindowId());
}
private:
void FocusWindowDirect(aura::Window* window) override {
ui::test::EventGenerator generator(root_window(), window);
generator.ClickLeftButton();
}
void ActivateWindowDirect(aura::Window* window) override {
ui::test::EventGenerator generator(root_window(), window);
generator.ClickLeftButton();
}
void DeactivateWindowDirect(aura::Window* window) override {
aura::Window* next_activatable =
test_focus_rules()->GetNextActivatableWindow(window);
ui::test::EventGenerator generator(root_window(), next_activatable);
generator.ClickLeftButton();
}
bool IsInputEvent() override { return true; }
ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
const override {
return ActivationChangeObserver::ActivationReason::INPUT_EVENT;
}
};
class FocusControllerMouseEnterEventTest
: public FocusControllerMouseEventTest {
public:
FocusControllerMouseEnterEventTest() {
scoped_feature_list_.InitAndEnableFeature(features::kFocusFollowsCursor);
}
void MouseEnteredEvent() {
aura::Window::Windows children_before = root_window()->children();
aura::Window* w2 = root_window()->GetChildById(2);
ui::test::EventGenerator generator(root_window(), w2);
generator.SendMouseEnter();
EXPECT_EQ(w2, GetActiveWindow());
EXPECT_EQ(children_before, root_window()->children());
}
void MouseEnteredWithActiveParent() {
aura::Window* w2 = root_window()->GetChildById(2);
aura::Window* w21 = root_window()->GetChildById(21);
ActivateWindow(w2);
ui::test::EventGenerator generator(root_window(), w21);
generator.SendMouseEnter();
EXPECT_EQ(w2, GetFocusedWindow());
}
base::test::ScopedFeatureList scoped_feature_list_;
};
class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
public:
FocusControllerGestureEventTest() {}
FocusControllerGestureEventTest(const FocusControllerGestureEventTest&) =
delete;
FocusControllerGestureEventTest& operator=(
const FocusControllerGestureEventTest&) = delete;
private:
void FocusWindowDirect(aura::Window* window) override {
ui::test::EventGenerator generator(root_window(), window);
generator.GestureTapAt(window->bounds().CenterPoint());
}
void ActivateWindowDirect(aura::Window* window) override {
ui::test::EventGenerator generator(root_window(), window);
generator.GestureTapAt(window->bounds().CenterPoint());
}
void DeactivateWindowDirect(aura::Window* window) override {
aura::Window* next_activatable =
test_focus_rules()->GetNextActivatableWindow(window);
ui::test::EventGenerator generator(root_window(), next_activatable);
generator.GestureTapAt(window->bounds().CenterPoint());
}
bool IsInputEvent() override { return true; }
ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
const override {
return ActivationChangeObserver::ActivationReason::INPUT_EVENT;
}
};
class FocusControllerImplicitTestBase : public FocusControllerTestBase {
public:
FocusControllerImplicitTestBase(const FocusControllerImplicitTestBase&) =
delete;
FocusControllerImplicitTestBase& operator=(
const FocusControllerImplicitTestBase&) = delete;
protected:
explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {}
aura::Window* GetDispositionWindow(aura::Window* window) {
return parent_ ? window->parent() : window;
}
ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
const {
return ActivationChangeObserver::ActivationReason::
WINDOW_DISPOSITION_CHANGED;
}
virtual void ChangeWindowDisposition(aura::Window* window) = 0;
virtual void PostDispositionChangeExpectations() {}
void BasicFocus() override {
EXPECT_FALSE(GetFocusedWindow());
aura::Window* w211 = root_window()->GetChildById(211);
FocusWindow(w211);
EXPECT_EQ(211, GetFocusedWindowId());
ChangeWindowDisposition(w211);
EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId());
}
void BasicActivation() override {
DCHECK(!parent_) << "Activation tests don't support parent changes.";
EXPECT_FALSE(GetActiveWindow());
aura::Window* w2 = root_window()->GetChildById(2);
ActivateWindow(w2);
EXPECT_EQ(2, GetActiveWindowId());
ChangeWindowDisposition(w2);
EXPECT_EQ(3, GetActiveWindowId());
PostDispositionChangeExpectations();
}
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);
}
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);
EXPECT_EQ(GetExpectedActivationReason(),
root_observer.last_activation_reason());
observer2.ExpectCounts(1, 1);
observer3.ExpectCounts(1, 1);
}
void FocusRulesOverride() override {
EXPECT_FALSE(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);
EXPECT_EQ(11, GetFocusedWindowId());
test_focus_rules()->set_focus_restriction(nullptr);
}
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);
ChangeWindowDisposition(w1);
EXPECT_EQ(3, GetActiveWindowId());
EXPECT_EQ(3, GetFocusedWindowId());
test_focus_rules()->set_focus_restriction(nullptr);
ActivateWindow(root_window()->GetChildById(2));
EXPECT_EQ(2, GetActiveWindowId());
EXPECT_EQ(2, GetFocusedWindowId());
}
private:
bool parent_;
};
class FocusControllerHideTest : public FocusControllerImplicitTestBase {
public:
FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {}
FocusControllerHideTest(const FocusControllerHideTest&) = delete;
FocusControllerHideTest& operator=(const FocusControllerHideTest&) = delete;
protected:
FocusControllerHideTest(bool parent)
: FocusControllerImplicitTestBase(parent) {}
void ChangeWindowDisposition(aura::Window* window) override {
GetDispositionWindow(window)->Hide();
}
};
class FocusControllerParentHideTest : public FocusControllerHideTest {
public:
FocusControllerParentHideTest() : FocusControllerHideTest(true) {}
FocusControllerParentHideTest(const FocusControllerParentHideTest&) = delete;
FocusControllerParentHideTest& operator=(
const FocusControllerParentHideTest&) = delete;
void TransientChildWindowActivationTest() {
aura::Window* w1 = root_window()->GetChildById(1);
aura::Window* w11 = root_window()->GetChildById(11);
::wm::AddTransientChild(w1, w11);
w11->SetProperty(aura::client::kModalKey, ui::mojom::ModalType::kWindow);
EXPECT_EQ(ui::mojom::ModalType::kNone,
w1->GetProperty(aura::client::kModalKey));
EXPECT_EQ(ui::mojom::ModalType::kWindow,
w11->GetProperty(aura::client::kModalKey));
w1->Hide();
w1->Show();
EXPECT_EQ(ui::mojom::ModalType::kNone,
w1->GetProperty(aura::client::kModalKey));
EXPECT_EQ(ui::mojom::ModalType::kWindow,
w11->GetProperty(aura::client::kModalKey));
}
};
class FocusControllerDestructionTest : public FocusControllerImplicitTestBase {
public:
FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {}
FocusControllerDestructionTest(const FocusControllerDestructionTest&) =
delete;
FocusControllerDestructionTest& operator=(
const FocusControllerDestructionTest&) = delete;
protected:
FocusControllerDestructionTest(bool parent)
: FocusControllerImplicitTestBase(parent) {}
void ChangeWindowDisposition(aura::Window* window) override {
delete GetDispositionWindow(window);
}
};
class FocusControllerParentDestructionTest
: public FocusControllerDestructionTest {
public:
FocusControllerParentDestructionTest()
: FocusControllerDestructionTest(true) {}
FocusControllerParentDestructionTest(
const FocusControllerParentDestructionTest&) = delete;
FocusControllerParentDestructionTest& operator=(
const FocusControllerParentDestructionTest&) = delete;
};
class FocusControllerRemovalTest : public FocusControllerImplicitTestBase {
public:
FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {}
FocusControllerRemovalTest(const FocusControllerRemovalTest&) = delete;
FocusControllerRemovalTest& operator=(const FocusControllerRemovalTest&) =
delete;
protected:
FocusControllerRemovalTest(bool parent)
: FocusControllerImplicitTestBase(parent) {}
void ChangeWindowDisposition(aura::Window* window) override {
aura::Window* disposition_window = GetDispositionWindow(window);
disposition_window->parent()->RemoveChild(disposition_window);
window_owner_.reset(disposition_window);
}
void TearDown() override {
window_owner_.reset();
FocusControllerImplicitTestBase::TearDown();
}
private:
std::unique_ptr<aura::Window> window_owner_;
};
class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
public:
FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {}
FocusControllerParentRemovalTest(const FocusControllerParentRemovalTest&) =
delete;
FocusControllerParentRemovalTest& operator=(
const FocusControllerParentRemovalTest&) = delete;
};
#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }
#define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerMouseEnterEventTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME)
#define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME)
#define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME) \
present due to workspace manager issues. \
FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \
FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME) \
FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)
#define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME) \
IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)
#define ALL_FOCUS_TESTS(TESTNAME) \
DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)
#define TARGET_FOCUS_TESTS(TESTNAME) \
DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)
ALL_FOCUS_TESTS(BasicFocus)
TARGET_FOCUS_TESTS(BasicActivation)
ALL_FOCUS_TESTS(FocusEvents)
DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents)
DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents)
TARGET_FOCUS_TESTS(ActivationEvents)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents)
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow)
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow)
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow)
ALL_FOCUS_TESTS(FocusRulesOverride)
TARGET_FOCUS_TESTS(ActivationRulesOverride)
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation)
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide)
DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, FocusChangeDuringDrag)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
ChangeFocusWhenNothingFocusedAndCaptured)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, StackWindowAtTopOnActivation)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
HideFocusedWindowDuringActivationLoss)
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ActivateWhileActivating)
FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest,
TransientChildWindowActivationTest)
FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, IgnoreHandledEvent)
FOCUS_CONTROLLER_TEST(FocusControllerMouseEnterEventTest, MouseEnteredEvent)
FOCUS_CONTROLLER_TEST(FocusControllerMouseEnterEventTest,
MouseEnteredWithActiveParent)
}