#include "ash/wm/overview/overview_focus_cycler.h"
#include "ash/accessibility/accessibility_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/shell.h"
#include "ash/test/ash_test_util.h"
#include "ash/wm/desks/desk_action_button.h"
#include "ash/wm/desks/desk_action_view.h"
#include "ash/wm/desks/desk_name_view.h"
#include "ash/wm/desks/desk_preview_view.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/desks_test_util.h"
#include "ash/wm/desks/overview_desk_bar_view.h"
#include "ash/wm/desks/templates/saved_desk_save_desk_button.h"
#include "ash/wm/overview/overview_focus_cycler.h"
#include "ash/wm/overview/overview_grid_test_api.h"
#include "ash/wm/overview/overview_item_view.h"
#include "ash/wm/overview/overview_test_base.h"
#include "ash/wm/overview/overview_test_util.h"
#include "ash/wm/splitview/split_view_setup_view.h"
#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
#include "ash/wm/window_util.h"
#include "base/test/scoped_feature_list.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/test/display_manager_test_api.h"
namespace ash {
class OverviewFocusCyclerTest : public OverviewTestBase,
public testing::WithParamInterface<bool> {
public:
OverviewFocusCyclerTest() = default;
OverviewFocusCyclerTest(const OverviewFocusCyclerTest&) = delete;
OverviewFocusCyclerTest& operator=(const OverviewFocusCyclerTest&) = delete;
~OverviewFocusCyclerTest() override = default;
bool AreDeskTemplatesEnabled() const { return GetParam(); }
views::View* GetFocusedView() {
return GetOverviewSession()->focus_cycler()->GetOverviewFocusedView();
}
void SetUp() override {
scoped_feature_list_.InitWithFeatureStates(
{{features::kDesksTemplates, AreDeskTemplatesEnabled()}});
OverviewTestBase::SetUp();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_P(OverviewFocusCyclerTest, BasicTabKeyNavigation) {
std::unique_ptr<aura::Window> window2 = CreateAppWindow();
std::unique_ptr<aura::Window> window1 = CreateAppWindow();
ToggleOverview();
const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
GetOverviewItemsForRoot(0);
auto* event_generator = GetEventGenerator();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_LEFT, event_generator);
EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
}
TEST_P(OverviewFocusCyclerTest, BasicTabKeyNavigationTablet) {
std::unique_ptr<aura::Window> window1 = CreateAppWindow();
std::unique_ptr<aura::Window> window2 = CreateAppWindow();
std::unique_ptr<aura::Window> window3 = CreateAppWindow();
TabletModeControllerTestApi().EnterTabletMode();
ToggleOverview();
const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
GetOverviewItemsForRoot(0);
auto* event_generator = GetEventGenerator();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(overview_windows[2]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_LEFT, event_generator);
EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
window_util::GetFocusedWindow());
}
TEST_P(OverviewFocusCyclerTest, CloseWindowWithKey) {
std::unique_ptr<aura::Window> window = CreateAppWindow();
ToggleOverview();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, GetEventGenerator());
PressAndReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
EXPECT_TRUE(
views::Widget::GetWidgetForNativeWindow(window.get())->IsClosed());
}
TEST_P(OverviewFocusCyclerTest, BasicArrowKeyNavigation) {
const size_t test_windows = 9;
std::vector<std::unique_ptr<aura::Window>> windows;
for (size_t i = test_windows; i > 0; --i) {
std::unique_ptr<aura::Window> window = CreateAppWindow();
window->SetId(i);
windows.push_back(std::move(window));
}
struct TestData {
ui::KeyboardCode key_code;
std::string msg;
std::vector<int> expected_ids;
};
std::vector<TestData> test_data = {
{ui::VKEY_RIGHT, "right", {1, 2, 3, 4, 5, 6, 7, 8, 9, 1}},
{ui::VKEY_DOWN, "down", {1, 2, 3, 4, 5, 6, 7, 8, 9, 1}},
{ui::VKEY_LEFT, "left", {9, 8, 7, 6, 5, 4, 3, 2, 1, 9}},
{ui::VKEY_UP, "up", {9, 8, 7, 6, 5, 4, 3, 2, 1, 9}}};
auto get_id_for_focused_window =
[](const std::vector<std::unique_ptr<OverviewItemBase>>& items) -> int {
aura::Window* window = window_util::GetFocusedWindow();
if (!window) {
return aura::Window::kInitialId;
}
for (const auto& item : items) {
if (window == item->item_widget()->GetNativeWindow()) {
return item->GetWindow()->GetId();
}
}
return aura::Window::kInitialId;
};
auto* event_generator = GetEventGenerator();
for (const TestData& test_case : test_data) {
SCOPED_TRACE("Using " + test_case.msg + " key.");
ToggleOverview();
const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
GetOverviewItemsForRoot(0);
std::vector<int> actual_ids;
for (size_t i = 0; i < test_windows + 1; ++i) {
SendKeyUntilOverviewItemIsFocused(test_case.key_code, event_generator);
actual_ids.push_back(get_id_for_focused_window(overview_windows));
}
EXPECT_THAT(test_case.expected_ids, actual_ids);
ToggleOverview();
}
}
TEST_P(OverviewFocusCyclerTest, BasicMultiMonitorArrowKeyNavigation) {
UpdateDisplay("500x400,500x400");
const gfx::Rect bounds1(100, 100);
const gfx::Rect bounds2(550, 0, 100, 100);
std::unique_ptr<aura::Window> window4 = CreateAppWindow(bounds2);
std::unique_ptr<aura::Window> window3 = CreateAppWindow(bounds2);
std::unique_ptr<aura::Window> window2 = CreateAppWindow(bounds1);
std::unique_ptr<aura::Window> window1 = CreateAppWindow(bounds1);
ToggleOverview();
auto* event_generator = GetEventGenerator();
const std::vector<std::unique_ptr<OverviewItemBase>>& overview_root1 =
GetOverviewItemsForRoot(0);
const std::vector<std::unique_ptr<OverviewItemBase>>& overview_root2 =
GetOverviewItemsForRoot(1);
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(overview_root1[0]->item_widget(), GetFocusedView()->GetWidget());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(overview_root1[1]->item_widget(), GetFocusedView()->GetWidget());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(overview_root2[0]->item_widget(), GetFocusedView()->GetWidget());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(overview_root2[1]->item_widget(), GetFocusedView()->GetWidget());
}
TEST_P(OverviewFocusCyclerTest, MultiMonitorReversedOrder) {
UpdateDisplay("500x400,500x400");
Shell::Get()->display_manager()->SetLayoutForCurrentDisplays(
display::test::CreateDisplayLayout(display_manager(),
display::DisplayPlacement::LEFT, 0));
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
std::unique_ptr<aura::Window> window2 = CreateAppWindow(gfx::Rect(100, 100));
std::unique_ptr<aura::Window> window1 =
CreateAppWindow(gfx::Rect(-450, 0, 100, 100));
ASSERT_EQ(root_windows[1], window1->GetRootWindow());
ASSERT_EQ(root_windows[0], window2->GetRootWindow());
ToggleOverview();
auto* event_generator = GetEventGenerator();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(GetOverviewItemForWindow(window1.get())->item_widget(),
GetFocusedView()->GetWidget());
ToggleOverview();
ToggleOverview();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_LEFT, event_generator);
EXPECT_EQ(GetOverviewItemForWindow(window2.get())->item_widget(),
GetFocusedView()->GetWidget());
}
TEST_P(OverviewFocusCyclerTest, ThreeMonitors) {
UpdateDisplay("500x400,500x400,500x400");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
std::unique_ptr<aura::Window> window3 =
CreateAppWindow(gfx::Rect(1000, 0, 100, 100));
std::unique_ptr<aura::Window> window2 =
CreateAppWindow(gfx::Rect(500, 0, 100, 100));
std::unique_ptr<aura::Window> window1 = CreateAppWindow(gfx::Rect(100, 100));
EXPECT_EQ(root_windows[0], window1->GetRootWindow());
EXPECT_EQ(root_windows[1], window2->GetRootWindow());
EXPECT_EQ(root_windows[2], window3->GetRootWindow());
ToggleOverview();
auto* event_generator = GetEventGenerator();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(GetOverviewItemForWindow(window3.get())->item_widget(),
GetFocusedView()->GetWidget());
window3.reset();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(GetFocusedView());
ToggleOverview();
window3 = CreateTestWindow(gfx::Rect(1000, 0, 100, 100));
ToggleOverview();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(GetOverviewItemForWindow(window3.get())->item_widget(),
GetFocusedView()->GetWidget());
window2.reset();
EXPECT_EQ(GetOverviewItemForWindow(window3.get())->item_widget(),
GetFocusedView()->GetWidget());
}
TEST_P(OverviewFocusCyclerTest, FocusOverviewWindowWithReturnKey) {
std::unique_ptr<aura::Window> window2 = CreateAppWindow();
std::unique_ptr<aura::Window> window1 = CreateAppWindow();
ToggleOverview();
PressAndReleaseKey(ui::VKEY_RETURN);
OverviewController* overview_controller = OverviewController::Get();
EXPECT_TRUE(overview_controller->InOverviewSession());
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_RETURN);
EXPECT_FALSE(overview_controller->InOverviewSession());
EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
ToggleOverview();
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_RETURN);
EXPECT_FALSE(OverviewController::Get()->InOverviewSession());
EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
}
TEST_P(OverviewFocusCyclerTest, FocusLocationWhileDragging) {
std::unique_ptr<aura::Window> window1 = CreateAppWindow();
std::unique_ptr<aura::Window> window2 = CreateAppWindow();
std::unique_ptr<aura::Window> window3 = CreateAppWindow();
ToggleOverview();
auto* event_generator = GetEventGenerator();
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
OverviewItemBase* item3 = GetOverviewItemForWindow(window3.get());
EXPECT_EQ(item3->item_widget()->GetContentsView(), GetFocusedView());
DragItemToPoint(item3, gfx::Point(20, 20), event_generator,
false, false);
EXPECT_FALSE(GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_FALSE(GetFocusedView());
DragItemToPoint(item3, gfx::Point(300, 200), event_generator,
false, true);
EXPECT_FALSE(GetFocusedView());
SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
EXPECT_EQ(item3->item_widget()->GetContentsView(), GetFocusedView());
}
TEST_P(OverviewFocusCyclerTest, TabbingWithSplitview) {
std::unique_ptr<aura::Window> window1 = CreateAppWindow();
std::unique_ptr<aura::Window> window2 = CreateAppWindow();
ToggleOverview();
SplitViewController::Get(Shell::GetPrimaryRootWindow())
->SnapWindow(window1.get(), SnapPosition::kPrimary);
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(
GetOverviewItemForWindow(window2.get())->item_widget()->GetContentsView(),
GetFocusedView());
OverviewGrid* grid = GetOverviewSession()->grid_list()[0].get();
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(grid->GetSplitViewSetupView()->GetViewByID(
SplitViewSetupView::kDismissButtonIDForTest),
GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(grid->GetSplitViewSetupView()->GetViewByID(
SplitViewSetupView::kSettingsButtonIDForTest),
GetFocusedView());
}
class DesksOverviewFocusCyclerTest : public OverviewFocusCyclerTest {
public:
DesksOverviewFocusCyclerTest() = default;
DesksOverviewFocusCyclerTest(const DesksOverviewFocusCyclerTest&) = delete;
DesksOverviewFocusCyclerTest& operator=(const DesksOverviewFocusCyclerTest&) =
delete;
~DesksOverviewFocusCyclerTest() override = default;
const OverviewDeskBarView* GetDesksBarViewForRoot(aura::Window* root_window) {
OverviewGrid* grid =
GetOverviewSession()->GetGridWithRootWindow(root_window);
const OverviewDeskBarView* bar_view = grid->desks_bar_view();
CHECK(bar_view->IsZeroState() ^ grid->IsDesksBarViewActive());
return bar_view;
}
void SetUp() override {
OverviewFocusCyclerTest::SetUp();
auto* desk_controller = DesksController::Get();
desk_controller->NewDesk(DesksCreationRemovalSource::kButton);
ASSERT_EQ(2u, desk_controller->desks().size());
desk_controller->GetDeskAtIndex(1)->SetName(u"Desk 2", false);
}
protected:
static void CheckDeskBarViewSize(const OverviewDeskBarView* view,
const std::string& scope) {
SCOPED_TRACE(scope);
EXPECT_EQ(view->bounds().height(),
view->GetWidget()->GetWindowBoundsInScreen().height());
}
};
TEST_P(DesksOverviewFocusCyclerTest, TabbingBasic) {
base::AutoReset<bool> disable_app_id_check =
OverviewController::Get()->SetDisableAppIdCheckForTests();
std::unique_ptr<aura::Window> window1(CreateAppWindow(gfx::Rect(200, 200)));
std::unique_ptr<aura::Window> window2(CreateAppWindow(gfx::Rect(200, 200)));
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
CheckDeskBarViewSize(desk_bar_view, "initial");
ASSERT_EQ(2u, desk_bar_view->mini_views().size());
PressAndReleaseKey(ui::VKEY_TAB);
auto* item2 = GetOverviewItemForWindow(window2.get())
->GetLeafItemForWindow(window2.get());
EXPECT_EQ(item2->overview_item_view(), GetFocusedView());
CheckDeskBarViewSize(desk_bar_view, "overview item");
DeskMiniView* first_mini_view = desk_bar_view->mini_views()[0];
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(first_mini_view->desk_preview(), GetFocusedView());
CheckDeskBarViewSize(desk_bar_view, "first mini view");
PressAndReleaseKey(ui::VKEY_TAB);
const DeskActionView* desk_action_view = first_mini_view->desk_action_view();
EXPECT_EQ(desk_action_view->context_menu_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desk_action_view->close_all_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(first_mini_view->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desk_bar_view->new_desk_button(), GetFocusedView());
CheckDeskBarViewSize(desk_bar_view, "new desk button");
}
TEST_P(DesksOverviewFocusCyclerTest, TabbingReverse) {
base::AutoReset<bool> disable_app_id_check =
OverviewController::Get()->SetDisableAppIdCheckForTests();
std::unique_ptr<aura::Window> window1(CreateAppWindow(gfx::Rect(200, 200)));
std::unique_ptr<aura::Window> window2(CreateAppWindow(gfx::Rect(200, 200)));
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
ASSERT_EQ(2u, desk_bar_view->mini_views().size());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
EXPECT_EQ(desk_bar_view->new_desk_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
DeskMiniView* second_mini_view = desk_bar_view->mini_views()[1];
EXPECT_EQ(second_mini_view->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
EXPECT_EQ(second_mini_view->desk_action_view()->close_all_button(),
GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
EXPECT_EQ(second_mini_view->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
DeskMiniView* first_mini_view = desk_bar_view->mini_views()[0];
DeskActionView* first_action_view = first_mini_view->desk_action_view();
EXPECT_EQ(first_mini_view->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
EXPECT_EQ(first_action_view->close_all_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
EXPECT_EQ(first_action_view->context_menu_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
EXPECT_EQ(first_mini_view->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
auto* item1 = GetOverviewItemForWindow(window1.get())
->GetLeafItemForWindow(window1.get());
EXPECT_EQ(item1->overview_item_view(), GetFocusedView());
}
TEST_P(DesksOverviewFocusCyclerTest, TabbingMultiDisplay) {
base::AutoReset<bool> disable_app_id_check =
OverviewController::Get()->SetDisableAppIdCheckForTests();
UpdateDisplay("600x400,600x400,600x400");
aura::Window::Windows roots = Shell::GetAllRootWindows();
ASSERT_EQ(3u, roots.size());
std::unique_ptr<aura::Window> window1(CreateAppWindow(gfx::Rect(200, 200)));
std::unique_ptr<aura::Window> window2(CreateAppWindow(gfx::Rect(200, 200)));
std::unique_ptr<aura::Window> window3(
CreateAppWindow(gfx::Rect(600, 0, 200, 200)));
std::unique_ptr<aura::Window> window4(
CreateAppWindow(gfx::Rect(1200, 0, 200, 200)));
ASSERT_EQ(roots[0], window1->GetRootWindow());
ASSERT_EQ(roots[0], window2->GetRootWindow());
ASSERT_EQ(roots[1], window3->GetRootWindow());
ASSERT_EQ(roots[2], window4->GetRootWindow());
ToggleOverview();
const auto* desk_bar_view1 = GetDesksBarViewForRoot(roots[0]);
EXPECT_EQ(2u, desk_bar_view1->mini_views().size());
PressAndReleaseKey(ui::VKEY_TAB);
auto* item2 = GetOverviewItemForWindow(window2.get())
->GetLeafItemForWindow(window2.get());
EXPECT_EQ(item2->overview_item_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
auto* item1 = GetOverviewItemForWindow(window1.get())
->GetLeafItemForWindow(window1.get());
EXPECT_EQ(item1->overview_item_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
DeskMiniView* mini_view1 = desk_bar_view1->mini_views()[0];
DeskActionView* action_view1 = mini_view1->desk_action_view();
EXPECT_EQ(mini_view1->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(action_view1->context_menu_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(action_view1->close_all_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(mini_view1->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
DeskMiniView* mini_view2 = desk_bar_view1->mini_views()[1];
EXPECT_EQ(mini_view2->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(mini_view2->desk_action_view()->close_all_button(),
GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(mini_view2->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desk_bar_view1->new_desk_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
auto* item3 = GetOverviewItemForWindow(window3.get())
->GetLeafItemForWindow(window3.get());
EXPECT_EQ(item3->overview_item_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
const auto* desk_bar_view2 = GetDesksBarViewForRoot(roots[1]);
EXPECT_EQ(desk_bar_view2->mini_views()[0]->desk_preview(), GetFocusedView());
SendKey(ui::VKEY_TAB, GetEventGenerator(), ui::EF_NONE, 7);
EXPECT_EQ(desk_bar_view2->new_desk_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
auto* item4 = GetOverviewItemForWindow(window4.get())
->GetLeafItemForWindow(window4.get());
EXPECT_EQ(item4->overview_item_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
const auto* desk_bar_view3 = GetDesksBarViewForRoot(roots[2]);
EXPECT_EQ(desk_bar_view3->mini_views()[0]->desk_preview(), GetFocusedView());
SendKey(ui::VKEY_TAB, GetEventGenerator(), ui::EF_NONE, 7);
EXPECT_EQ(desk_bar_view3->new_desk_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(item2->overview_item_view(), GetFocusedView());
}
TEST_P(DesksOverviewFocusCyclerTest, TabbingChromevox) {
Shell::Get()->accessibility_controller()->spoken_feedback().SetEnabled(true);
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
EXPECT_EQ(2u, desk_bar_view->mini_views().size());
auto* mini_view1 = desk_bar_view->mini_views()[0].get();
auto* mini_view2 = desk_bar_view->mini_views()[1].get();
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(mini_view1->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
EXPECT_EQ(mini_view1->desk_action_view()->close_all_button(),
GetFocusedView());
PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
EXPECT_EQ(mini_view1->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
EXPECT_EQ(mini_view2->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
EXPECT_EQ(mini_view2->desk_action_view()->close_all_button(),
GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(mini_view2->desk_name_view(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
EXPECT_EQ(desk_bar_view->new_desk_button(), GetFocusedView());
}
TEST_P(DesksOverviewFocusCyclerTest, MiniViewAccelerator) {
const auto* desks_controller = DesksController::Get();
auto& desks = desks_controller->desks();
ASSERT_EQ(desks_controller->active_desk(), desks[0].get());
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
ASSERT_EQ(desk_bar_view->mini_views()[1]->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_SPACE);
DeskSwitchAnimationWaiter().Wait();
EXPECT_EQ(desks_controller->active_desk(), desks[1].get());
}
TEST_P(DesksOverviewFocusCyclerTest, CloseDeskWithMiniViewAccelerator) {
const auto* desks_controller = DesksController::Get();
ASSERT_EQ(2u, desks_controller->desks().size());
auto* desk1 = desks_controller->GetDeskAtIndex(0);
auto* desk2 = desks_controller->GetDeskAtIndex(1);
ASSERT_EQ(desk1, desks_controller->active_desk());
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
auto* mini_view2 = desk_bar_view->mini_views()[1].get();
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
ASSERT_EQ(mini_view2->desk_preview(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
EXPECT_EQ(1u, desks_controller->desks().size());
EXPECT_NE(desk2, desks_controller->GetDeskAtIndex(0));
EXPECT_FALSE(desk_bar_view->IsZeroState());
EXPECT_FALSE(desk_bar_view->mini_views().empty());
}
TEST_P(DesksOverviewFocusCyclerTest, DeskNameView) {
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
auto* desk_name_view_1 = desk_bar_view->mini_views()[0]->desk_name_view();
auto* desk_1 = DesksController::Get()->GetDeskAtIndex(0);
const std::u16string original_name = desk_1->name();
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desk_name_view_1, GetFocusedView());
EXPECT_TRUE(desk_name_view_1->HasFocus());
EXPECT_TRUE(desk_bar_view->IsDeskNameBeingModified());
EXPECT_TRUE(desk_name_view_1->HasSelection());
EXPECT_EQ(original_name, desk_name_view_1->GetSelectedText());
PressAndReleaseKey(ui::VKEY_RIGHT);
PressAndReleaseKey(ui::VKEY_LEFT);
EXPECT_EQ(desk_name_view_1, GetFocusedView());
EXPECT_TRUE(desk_name_view_1->HasFocus());
PressAndReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
PressAndReleaseKey(ui::VKEY_BACK);
EXPECT_EQ(u"", desk_name_view_1->GetText());
PressAndReleaseKey(ui::VKEY_C);
PressAndReleaseKey(ui::VKEY_O);
PressAndReleaseKey(ui::VKEY_D);
PressAndReleaseKey(ui::VKEY_E);
EXPECT_EQ(u"code", desk_name_view_1->GetText());
EXPECT_EQ(original_name, desk_1->name());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_FALSE(desk_name_view_1->HasFocus());
EXPECT_EQ(u"code", desk_1->name());
EXPECT_TRUE(desk_1->is_name_set_by_user());
}
TEST_P(DesksOverviewFocusCyclerTest, RemoveDeskWhileNameFocused) {
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
auto* desk_name_view_1 = desk_bar_view->mini_views()[0]->desk_name_view();
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desk_name_view_1, GetFocusedView());
const auto* desks_controller = DesksController::Get();
auto* desk_1 = desks_controller->GetDeskAtIndex(0);
RemoveDesk(desk_1);
RunScheduledLayoutForAllOverviewDeskBars();
EXPECT_EQ(nullptr, GetFocusedView());
EXPECT_FALSE(desk_bar_view->IsZeroState());
PressAndReleaseKey(ui::VKEY_TAB);
RunScheduledLayoutForAllOverviewDeskBars();
EXPECT_EQ(desk_bar_view->mini_views()[0]->desk_preview(), GetFocusedView());
}
TEST_P(DesksOverviewFocusCyclerTest, NewDesksWithKeyboard) {
UpdateDisplay("1200x800");
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
ASSERT_FALSE(desk_bar_view->IsZeroState());
const views::LabelButton* new_desk_button = desk_bar_view->new_desk_button();
const auto* desks_controller = DesksController::Get();
auto check_name_view_at_index = [this, desks_controller](
const auto* desk_bar_view, int index) {
const auto* desk_name_view =
desk_bar_view->mini_views()[index]->desk_name_view();
EXPECT_TRUE(desk_name_view->HasFocus());
if (desks_controller->CanCreateDesks()) {
EXPECT_EQ(desk_name_view, GetFocusedView());
}
EXPECT_EQ(std::u16string(), desk_name_view->GetText());
};
for (int i = 0; i < 7; ++i) {
PressAndReleaseKey(ui::VKEY_TAB);
}
ASSERT_EQ(new_desk_button, GetFocusedView());
while (desks_controller->CanCreateDesks()) {
PressAndReleaseKey(ui::VKEY_SPACE);
RunScheduledLayoutForAllOverviewDeskBars();
check_name_view_at_index(desk_bar_view,
desks_controller->desks().size() - 1);
PressAndReleaseKey(ui::VKEY_TAB);
}
EXPECT_FALSE(new_desk_button->GetEnabled());
EXPECT_EQ(desks_util::GetMaxNumberOfDesks(),
desks_controller->desks().size());
}
TEST_P(DesksOverviewFocusCyclerTest, ZeroStateOfDesksBar) {
ToggleOverview();
auto* desks_bar_view = GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
ASSERT_FALSE(desks_bar_view->IsZeroState());
ASSERT_EQ(2u, desks_bar_view->mini_views().size());
auto* mini_view = desks_bar_view->mini_views()[1].get();
GetEventGenerator()->MoveMouseTo(
mini_view->GetBoundsInScreen().CenterPoint());
EXPECT_TRUE(GetDeskActionVisibilityForMiniView(mini_view));
LeftClickOn(GetCloseDeskButtonForMiniView(mini_view));
ASSERT_FALSE(desks_bar_view->IsZeroState());
ToggleOverview();
ToggleOverview();
ASSERT_TRUE(OverviewController::Get()->InOverviewSession());
desks_bar_view = GetOverviewSession()
->GetGridWithRootWindow(Shell::GetPrimaryRootWindow())
->desks_bar_view();
ASSERT_TRUE(desks_bar_view->IsZeroState());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desks_bar_view->default_desk_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_TAB);
EXPECT_EQ(desks_bar_view->new_desk_button(), GetFocusedView());
PressAndReleaseKey(ui::VKEY_SPACE);
EXPECT_EQ(desks_bar_view->mini_views()[1]->desk_name_view(),
GetFocusedView());
}
TEST_P(DesksOverviewFocusCyclerTest, ClickingNameViewMovesFocus) {
ToggleOverview();
const auto* desk_bar_view =
GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
CheckDeskBarViewSize(desk_bar_view, "initial");
ASSERT_EQ(2u, desk_bar_view->mini_views().size());
PressAndReleaseKey(ui::VKEY_TAB);
ASSERT_EQ(desk_bar_view->mini_views()[0]->desk_preview(), GetFocusedView());
CheckDeskBarViewSize(desk_bar_view, "tabbed once");
auto* event_generator = GetEventGenerator();
auto* desk_name_view_1 = desk_bar_view->mini_views()[1]->desk_name_view();
event_generator->MoveMouseTo(
desk_name_view_1->GetBoundsInScreen().CenterPoint());
event_generator->ClickLeftButton();
EXPECT_FALSE(desk_bar_view->IsZeroState());
EXPECT_EQ(desk_name_view_1, GetFocusedView());
}
TEST_P(DesksOverviewFocusCyclerTest, SwitchingToZeroStateWhileTabbing) {
ToggleOverview();
auto* desks_bar_view = GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
ASSERT_FALSE(desks_bar_view->IsZeroState());
ASSERT_EQ(2u, desks_bar_view->mini_views().size());
PressAndReleaseKey(ui::VKEY_TAB);
ASSERT_EQ(desks_bar_view->mini_views()[0]->desk_preview(), GetFocusedView());
auto* mini_view = desks_bar_view->mini_views()[1].get();
GetEventGenerator()->MoveMouseTo(
mini_view->GetBoundsInScreen().CenterPoint());
ASSERT_TRUE(GetDeskActionVisibilityForMiniView(mini_view));
LeftClickOn(GetCloseDeskButtonForMiniView(mini_view));
ASSERT_FALSE(desks_bar_view->IsZeroState());
PressAndReleaseKey(ui::VKEY_TAB);
}
INSTANTIATE_TEST_SUITE_P(All, OverviewFocusCyclerTest, testing::Bool());
INSTANTIATE_TEST_SUITE_P(All, DesksOverviewFocusCyclerTest, testing::Bool());
}