blob: be940691174083909adf22dd793120386578d0ad [file] [log] [blame]
Avi Drissman3a215d1e2022-09-07 19:43:091// Copyright 2012 The Chromium Authors
[email protected]df1c9862012-02-27 10:37:312// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
James Cookb0bf8e82017-04-09 17:01:445#include "ash/focus_cycler.h"
[email protected]df1c9862012-02-27 10:37:316
dchenga94547472016-04-08 08:41:117#include <memory>
8
James Cook840177e2017-05-25 02:20:019#include "ash/shelf/shelf.h"
Manu Cornete11c3c352019-07-31 06:13:4110#include "ash/shelf/shelf_focus_cycler.h"
11#include "ash/shelf/shelf_navigation_widget.h"
James Cookb0bf8e82017-04-09 17:01:4412#include "ash/shelf/shelf_widget.h"
sky79fa34712017-03-20 23:46:4713#include "ash/shell.h"
James Cookb0bf8e82017-04-09 17:01:4414#include "ash/system/status_area_widget.h"
15#include "ash/system/status_area_widget_delegate.h"
[email protected]df1c9862012-02-27 10:37:3116#include "ash/test/ash_test_base.h"
[email protected]864b58552013-12-19 04:19:3817#include "ash/wm/window_util.h"
[email protected]df1c9862012-02-27 10:37:3118#include "ui/aura/test/test_windows.h"
19#include "ui/aura/window.h"
[email protected]fcc51c952014-02-21 21:31:2620#include "ui/aura/window_event_dispatcher.h"
[email protected]73c9fd02014-07-28 01:48:5221#include "ui/events/test/event_generator.h"
[email protected]242aa4f2013-04-30 01:04:0822#include "ui/views/accessible_pane_view.h"
[email protected]df1c9862012-02-27 10:37:3123#include "ui/views/controls/button/menu_button.h"
24#include "ui/views/widget/widget.h"
25
26namespace ash {
[email protected]df1c9862012-02-27 10:37:3127
[email protected]df1c9862012-02-27 10:37:3128using aura::Window;
[email protected]df1c9862012-02-27 10:37:3129
[email protected]8676f0472012-03-29 20:30:1230namespace {
31
[email protected]093b8d642014-04-03 20:59:2832StatusAreaWidgetDelegate* GetStatusAreaWidgetDelegate(views::Widget* widget) {
33 return static_cast<StatusAreaWidgetDelegate*>(widget->GetContentsView());
[email protected]8676f0472012-03-29 20:30:1234}
35
[email protected]242aa4f2013-04-30 01:04:0836class PanedWidgetDelegate : public views::WidgetDelegate {
37 public:
38 PanedWidgetDelegate(views::Widget* widget) : widget_(widget) {}
39
40 void SetAccessiblePanes(const std::vector<views::View*>& panes) {
41 accessible_panes_ = panes;
42 }
43
Peter Kasting9ffb58bc72020-01-13 17:28:0544 // views::WidgetDelegate:
dcheng222b9c72015-01-16 00:48:0145 void GetAccessiblePanes(std::vector<views::View*>* panes) override {
jamescookb8dcef522016-06-25 14:42:5546 std::copy(accessible_panes_.begin(), accessible_panes_.end(),
[email protected]242aa4f2013-04-30 01:04:0847 std::back_inserter(*panes));
48 }
Allen Bauerd66100e2020-02-10 18:11:4349 views::Widget* GetWidget() override { return widget_; }
50 const views::Widget* GetWidget() const override { return widget_; }
[email protected]242aa4f2013-04-30 01:04:0851
52 private:
53 views::Widget* widget_;
54 std::vector<views::View*> accessible_panes_;
55};
56
[email protected]8676f0472012-03-29 20:30:1257} // namespace
58
[email protected]eb5a0ab2012-10-20 00:50:2559class FocusCyclerTest : public AshTestBase {
60 public:
Chris Watkinsc24daf62017-11-28 03:43:0961 FocusCyclerTest() = default;
[email protected]df1c9862012-02-27 10:37:3162
Peter Boström5fc1d312021-09-24 02:32:1563 FocusCyclerTest(const FocusCyclerTest&) = delete;
64 FocusCyclerTest& operator=(const FocusCyclerTest&) = delete;
65
dcheng222b9c72015-01-16 00:48:0166 void SetUp() override {
[email protected]eb5a0ab2012-10-20 00:50:2567 AshTestBase::SetUp();
[email protected]df1c9862012-02-27 10:37:3168
Peter Boström6b701822021-04-15 03:53:0869 focus_cycler_ = std::make_unique<FocusCycler>();
[email protected]eb5a0ab2012-10-20 00:50:2570 }
71
dcheng222b9c72015-01-16 00:48:0172 void TearDown() override {
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:2373 GetStatusAreaWidgetDelegate(GetPrimaryStatusAreaWidget())
warx7f3974192016-06-25 00:12:5674 ->SetFocusCyclerForTesting(nullptr);
[email protected]eb5a0ab2012-10-20 00:50:2575
Manu Cornet55cfe062020-02-03 22:28:2276 GetPrimaryShelf()->shelf_widget()->SetFocusCycler(nullptr);
[email protected]eb5a0ab2012-10-20 00:50:2577
78 focus_cycler_.reset();
79
80 AshTestBase::TearDown();
81 }
82
83 protected:
jamescookfe89c292017-03-10 18:03:2384 // Setup the system tray focus cycler.
warx7f3974192016-06-25 00:12:5685 void SetUpTrayFocusCycle() {
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:2386 views::Widget* system_tray_widget = GetPrimaryStatusAreaWidget();
warx7f3974192016-06-25 00:12:5687 ASSERT_TRUE(system_tray_widget);
88 focus_cycler_->AddWidget(system_tray_widget);
89 GetStatusAreaWidgetDelegate(system_tray_widget)
90 ->SetFocusCyclerForTesting(focus_cycler());
[email protected]eb5a0ab2012-10-20 00:50:2591 }
92
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:2393 views::Widget* GetPrimaryStatusAreaWidget() {
94 return GetPrimaryShelf()->GetStatusAreaWidget();
95 }
96
[email protected]eb5a0ab2012-10-20 00:50:2597 FocusCycler* focus_cycler() { return focus_cycler_.get(); }
98
[email protected]478c6c32013-03-09 02:50:5899 void InstallFocusCycleOnShelf() {
100 // Add the shelf.
Manu Cornet55cfe062020-02-03 22:28:22101 GetPrimaryShelf()->hotseat_widget()->SetFocusCycler(focus_cycler());
[email protected]eb5a0ab2012-10-20 00:50:25102 }
103
104 private:
dchenga94547472016-04-08 08:41:11105 std::unique_ptr<FocusCycler> focus_cycler_;
[email protected]eb5a0ab2012-10-20 00:50:25106};
107
108TEST_F(FocusCyclerTest, CycleFocusBrowserOnly) {
[email protected]df1c9862012-02-27 10:37:31109 // Create a single test window.
dchenga94547472016-04-08 08:41:11110 std::unique_ptr<Window> window0(CreateTestWindowInShellWithId(0));
[email protected]f3c7b252012-02-27 12:17:54111 wm::ActivateWindow(window0.get());
112 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]df1c9862012-02-27 10:37:31113
114 // Cycle the window
[email protected]eb5a0ab2012-10-20 00:50:25115 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
[email protected]f3c7b252012-02-27 12:17:54116 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]df1c9862012-02-27 10:37:31117}
118
[email protected]eb5a0ab2012-10-20 00:50:25119TEST_F(FocusCyclerTest, CycleFocusForward) {
warx7f3974192016-06-25 00:12:56120 SetUpTrayFocusCycle();
[email protected]df1c9862012-02-27 10:37:31121
[email protected]478c6c32013-03-09 02:50:58122 InstallFocusCycleOnShelf();
[email protected]df1c9862012-02-27 10:37:31123
124 // Create a single test window.
dchenga94547472016-04-08 08:41:11125 std::unique_ptr<Window> window0(CreateTestWindowInShellWithId(0));
[email protected]f3c7b252012-02-27 12:17:54126 wm::ActivateWindow(window0.get());
127 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]df1c9862012-02-27 10:37:31128
[email protected]478c6c32013-03-09 02:50:58129 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25130 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23131 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]df1c9862012-02-27 10:37:31132
[email protected]478c6c32013-03-09 02:50:58133 // Cycle focus to the shelf.
[email protected]eb5a0ab2012-10-20 00:50:25134 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Manu Cornet55cfe062020-02-03 22:28:22135 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]df1c9862012-02-27 10:37:31136
[email protected]478c6c32013-03-09 02:50:58137 // Cycle focus to the browser.
[email protected]eb5a0ab2012-10-20 00:50:25138 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
[email protected]f3c7b252012-02-27 12:17:54139 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]df1c9862012-02-27 10:37:31140}
141
[email protected]eb5a0ab2012-10-20 00:50:25142TEST_F(FocusCyclerTest, CycleFocusBackward) {
warx7f3974192016-06-25 00:12:56143 SetUpTrayFocusCycle();
[email protected]df1c9862012-02-27 10:37:31144
[email protected]478c6c32013-03-09 02:50:58145 InstallFocusCycleOnShelf();
[email protected]df1c9862012-02-27 10:37:31146
147 // Create a single test window.
dchenga94547472016-04-08 08:41:11148 std::unique_ptr<Window> window0(CreateTestWindowInShellWithId(0));
[email protected]f3c7b252012-02-27 12:17:54149 wm::ActivateWindow(window0.get());
150 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]df1c9862012-02-27 10:37:31151
[email protected]478c6c32013-03-09 02:50:58152 // Cycle focus to the shelf.
[email protected]eb5a0ab2012-10-20 00:50:25153 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Manu Cornet55cfe062020-02-03 22:28:22154 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]df1c9862012-02-27 10:37:31155
[email protected]478c6c32013-03-09 02:50:58156 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25157 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23158 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]df1c9862012-02-27 10:37:31159
[email protected]478c6c32013-03-09 02:50:58160 // Cycle focus to the browser.
[email protected]eb5a0ab2012-10-20 00:50:25161 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
[email protected]f3c7b252012-02-27 12:17:54162 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]df1c9862012-02-27 10:37:31163}
164
[email protected]eb5a0ab2012-10-20 00:50:25165TEST_F(FocusCyclerTest, CycleFocusForwardBackward) {
warx7f3974192016-06-25 00:12:56166 SetUpTrayFocusCycle();
[email protected]ce711ac2012-06-14 07:05:41167
[email protected]478c6c32013-03-09 02:50:58168 InstallFocusCycleOnShelf();
[email protected]ce711ac2012-06-14 07:05:41169
170 // Create a single test window.
dchenga94547472016-04-08 08:41:11171 std::unique_ptr<Window> window0(CreateTestWindowInShellWithId(0));
[email protected]ce711ac2012-06-14 07:05:41172 wm::ActivateWindow(window0.get());
173 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
174
[email protected]478c6c32013-03-09 02:50:58175 // Cycle focus to the shelf.
[email protected]eb5a0ab2012-10-20 00:50:25176 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Manu Cornet55cfe062020-02-03 22:28:22177 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41178
[email protected]478c6c32013-03-09 02:50:58179 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25180 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23181 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41182
[email protected]478c6c32013-03-09 02:50:58183 // Cycle focus to the browser.
[email protected]eb5a0ab2012-10-20 00:50:25184 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
[email protected]ce711ac2012-06-14 07:05:41185 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
186
[email protected]478c6c32013-03-09 02:50:58187 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25188 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23189 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41190
[email protected]478c6c32013-03-09 02:50:58191 // Cycle focus to the shelf.
[email protected]eb5a0ab2012-10-20 00:50:25192 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Manu Cornet55cfe062020-02-03 22:28:22193 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41194
[email protected]478c6c32013-03-09 02:50:58195 // Cycle focus to the browser.
[email protected]eb5a0ab2012-10-20 00:50:25196 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
[email protected]ce711ac2012-06-14 07:05:41197 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
198}
199
[email protected]eb5a0ab2012-10-20 00:50:25200TEST_F(FocusCyclerTest, CycleFocusNoBrowser) {
warx7f3974192016-06-25 00:12:56201 SetUpTrayFocusCycle();
[email protected]ce711ac2012-06-14 07:05:41202
[email protected]478c6c32013-03-09 02:50:58203 InstallFocusCycleOnShelf();
[email protected]ce711ac2012-06-14 07:05:41204
[email protected]478c6c32013-03-09 02:50:58205 // Add the shelf and focus it.
Manu Cornet55cfe062020-02-03 22:28:22206 focus_cycler()->FocusWidget(GetPrimaryShelf()->hotseat_widget());
[email protected]ce711ac2012-06-14 07:05:41207
[email protected]478c6c32013-03-09 02:50:58208 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25209 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23210 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41211
[email protected]478c6c32013-03-09 02:50:58212 // Cycle focus to the shelf.
[email protected]eb5a0ab2012-10-20 00:50:25213 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Manu Cornet55cfe062020-02-03 22:28:22214 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41215
[email protected]478c6c32013-03-09 02:50:58216 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25217 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23218 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41219
[email protected]478c6c32013-03-09 02:50:58220 // Cycle focus to the shelf.
[email protected]eb5a0ab2012-10-20 00:50:25221 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Manu Cornet55cfe062020-02-03 22:28:22222 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41223
[email protected]478c6c32013-03-09 02:50:58224 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25225 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23226 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]ce711ac2012-06-14 07:05:41227}
228
[email protected]fba1eb22014-03-12 21:12:50229// Tests that focus cycles from the active browser to the status area and back.
[email protected]478c6c32013-03-09 02:50:58230TEST_F(FocusCyclerTest, Shelf_CycleFocusForward) {
warx7f3974192016-06-25 00:12:56231 SetUpTrayFocusCycle();
[email protected]478c6c32013-03-09 02:50:58232 InstallFocusCycleOnShelf();
Manu Cornet55cfe062020-02-03 22:28:22233 GetPrimaryShelf()->hotseat_widget()->Hide();
[email protected]057dc5752012-03-06 23:59:31234
[email protected]fba1eb22014-03-12 21:12:50235 // Create two test windows.
dchenga94547472016-04-08 08:41:11236 std::unique_ptr<Window> window0(CreateTestWindowInShellWithId(0));
237 std::unique_ptr<Window> window1(CreateTestWindowInShellWithId(1));
[email protected]fba1eb22014-03-12 21:12:50238 wm::ActivateWindow(window1.get());
[email protected]057dc5752012-03-06 23:59:31239 wm::ActivateWindow(window0.get());
240 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
241
[email protected]478c6c32013-03-09 02:50:58242 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25243 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23244 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]057dc5752012-03-06 23:59:31245
[email protected]478c6c32013-03-09 02:50:58246 // Cycle focus to the browser.
[email protected]eb5a0ab2012-10-20 00:50:25247 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
[email protected]057dc5752012-03-06 23:59:31248 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
[email protected]fba1eb22014-03-12 21:12:50249
250 // Cycle focus to the status area.
251 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23252 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]057dc5752012-03-06 23:59:31253}
254
[email protected]478c6c32013-03-09 02:50:58255TEST_F(FocusCyclerTest, Shelf_CycleFocusBackwardInvisible) {
warx7f3974192016-06-25 00:12:56256 SetUpTrayFocusCycle();
[email protected]478c6c32013-03-09 02:50:58257 InstallFocusCycleOnShelf();
Manu Cornet55cfe062020-02-03 22:28:22258 GetPrimaryShelf()->hotseat_widget()->Hide();
[email protected]057dc5752012-03-06 23:59:31259
260 // Create a single test window.
dchenga94547472016-04-08 08:41:11261 std::unique_ptr<Window> window0(CreateTestWindowInShellWithId(0));
[email protected]057dc5752012-03-06 23:59:31262 wm::ActivateWindow(window0.get());
263 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
264
[email protected]478c6c32013-03-09 02:50:58265 // Cycle focus to the status area.
[email protected]eb5a0ab2012-10-20 00:50:25266 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23267 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]057dc5752012-03-06 23:59:31268
[email protected]478c6c32013-03-09 02:50:58269 // Cycle focus to the browser.
[email protected]eb5a0ab2012-10-20 00:50:25270 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
[email protected]057dc5752012-03-06 23:59:31271 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
272}
273
[email protected]242aa4f2013-04-30 01:04:08274TEST_F(FocusCyclerTest, CycleFocusThroughWindowWithPanes) {
warx7f3974192016-06-25 00:12:56275 SetUpTrayFocusCycle();
[email protected]242aa4f2013-04-30 01:04:08276
277 InstallFocusCycleOnShelf();
278
dchenga94547472016-04-08 08:41:11279 std::unique_ptr<PanedWidgetDelegate> test_widget_delegate;
280 std::unique_ptr<views::Widget> browser_widget(new views::Widget);
Peter Boström6b701822021-04-15 03:53:08281 test_widget_delegate =
282 std::make_unique<PanedWidgetDelegate>(browser_widget.get());
[email protected]242aa4f2013-04-30 01:04:08283 views::Widget::InitParams widget_params(
284 views::Widget::InitParams::TYPE_WINDOW);
[email protected]464a0012013-11-12 18:22:44285 widget_params.delegate = test_widget_delegate.get();
[email protected]242aa4f2013-04-30 01:04:08286 widget_params.ownership =
287 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
Peter Kasting97defc92020-03-05 18:49:02288 widget_params.context = GetContext();
Ahmed Fakhry32f3c452019-08-01 16:36:34289 browser_widget->Init(std::move(widget_params));
[email protected]242aa4f2013-04-30 01:04:08290 browser_widget->Show();
291
292 aura::Window* browser_window = browser_widget->GetNativeView();
293
294 views::View* root_view = browser_widget->GetRootView();
295
Manu Cornete11c3c352019-07-31 06:13:41296 // pane1 contains view1 and view2, pane2 contains view3 and view4.
[email protected]242aa4f2013-04-30 01:04:08297 views::AccessiblePaneView* pane1 = new views::AccessiblePaneView();
298 root_view->AddChildView(pane1);
299
300 views::View* view1 = new views::View;
karandeepbe7ad02a2016-04-27 23:57:22301 view1->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
[email protected]242aa4f2013-04-30 01:04:08302 pane1->AddChildView(view1);
303
304 views::View* view2 = new views::View;
karandeepbe7ad02a2016-04-27 23:57:22305 view2->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
[email protected]242aa4f2013-04-30 01:04:08306 pane1->AddChildView(view2);
307
308 views::AccessiblePaneView* pane2 = new views::AccessiblePaneView();
309 root_view->AddChildView(pane2);
310
311 views::View* view3 = new views::View;
karandeepbe7ad02a2016-04-27 23:57:22312 view3->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
[email protected]242aa4f2013-04-30 01:04:08313 pane2->AddChildView(view3);
314
315 views::View* view4 = new views::View;
karandeepbe7ad02a2016-04-27 23:57:22316 view4->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
[email protected]242aa4f2013-04-30 01:04:08317 pane2->AddChildView(view4);
318
319 std::vector<views::View*> panes;
320 panes.push_back(pane1);
321 panes.push_back(pane2);
322
323 test_widget_delegate->SetAccessiblePanes(panes);
324
325 views::FocusManager* focus_manager = browser_widget->GetFocusManager();
326
327 // Cycle focus to the status area.
328 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23329 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]242aa4f2013-04-30 01:04:08330
331 // Cycle focus to the shelf.
332 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Manu Cornet55cfe062020-02-03 22:28:22333 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]242aa4f2013-04-30 01:04:08334
335 // Cycle focus to the first pane in the browser.
336 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
337 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
338 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
339
340 // Cycle focus to the second pane in the browser.
341 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
342 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
343 EXPECT_EQ(focus_manager->GetFocusedView(), view3);
344
345 // Cycle focus back to the status area.
346 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23347 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]242aa4f2013-04-30 01:04:08348
349 // Reverse direction - back to the second pane in the browser.
350 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
351 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
352 EXPECT_EQ(focus_manager->GetFocusedView(), view3);
353
354 // Back to the first pane in the browser.
355 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
356 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
357 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
358
359 // Back to the shelf.
360 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Manu Cornet55cfe062020-02-03 22:28:22361 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
[email protected]242aa4f2013-04-30 01:04:08362
363 // Back to the status area.
364 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
Tetsui Ohkubo2b2fe2d2018-06-01 17:01:23365 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
[email protected]242aa4f2013-04-30 01:04:08366
367 // Pressing "Escape" while on the status area should
368 // deactivate it, and activate the browser window.
James Cook70501b22021-08-09 17:19:18369 PressAndReleaseKey(ui::VKEY_ESCAPE);
[email protected]242aa4f2013-04-30 01:04:08370 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
371 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
372
Manu Cornete11c3c352019-07-31 06:13:41373 // Similarly, pressing "Escape" while on the shelf should do the same thing.
374 // Focus the navigation widget directly because the shelf has no apps here.
375 GetPrimaryShelf()->shelf_focus_cycler()->FocusNavigation(false /* last */);
Manu Cornet55cfe062020-02-03 22:28:22376 EXPECT_TRUE(GetPrimaryShelf()->navigation_widget()->IsActive());
James Cook70501b22021-08-09 17:19:18377 PressAndReleaseKey(ui::VKEY_ESCAPE);
[email protected]242aa4f2013-04-30 01:04:08378 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
379 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
380}
381
xdai063763f2015-09-29 00:09:07382// Test that when the shelf widget & status area widget are removed, they should
383// also be removed from focus cycler.
384TEST_F(FocusCyclerTest, RemoveWidgetOnDisplayRemoved) {
385 // Two displays are added, so two shelf widgets and two status area widgets
386 // are added to focus cycler.
Mitsuru Oshimaa97d1e52021-10-05 08:27:42387 UpdateDisplay("800x700, 600x500");
xdai063763f2015-09-29 00:09:07388 // Remove one display. Its shelf widget and status area widget should also be
389 // removed from focus cycler.
Mitsuru Oshima53bbcd72021-08-14 03:59:21390 UpdateDisplay("800x700");
xdai063763f2015-09-29 00:09:07391
392 // Create a single test window.
dchenga94547472016-04-08 08:41:11393 std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
xdai063763f2015-09-29 00:09:07394 wm::ActivateWindow(window.get());
395 EXPECT_TRUE(wm::IsActiveWindow(window.get()));
396
Manu Cornete11c3c352019-07-31 06:13:41397 // Cycle focus to the navigation widget.
398 Shell::Get()->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Manu Cornet55cfe062020-02-03 22:28:22399 EXPECT_TRUE(GetPrimaryShelf()->navigation_widget()->IsActive());
Manu Cornete11c3c352019-07-31 06:13:41400
Manu Cornetaef0c112019-08-19 19:35:24401 // Cycle focus to the hotseat widget.
402 Shell::Get()->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
Manu Cornet55cfe062020-02-03 22:28:22403 EXPECT_TRUE(GetPrimaryShelf()->hotseat_widget()->IsActive());
xdai063763f2015-09-29 00:09:07404
Alex Newcomer6be08332020-04-17 19:00:43405 // Cycle focus to the status area.
406 Shell::Get()->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
407 EXPECT_TRUE(GetPrimaryStatusAreaWidget()->IsActive());
408
xdai063763f2015-09-29 00:09:07409 // Cycle focus should go back to the browser.
sky79fa34712017-03-20 23:46:47410 Shell::Get()->focus_cycler()->RotateFocus(FocusCycler::FORWARD);
xdai063763f2015-09-29 00:09:07411 EXPECT_TRUE(wm::IsActiveWindow(window.get()));
412}
413
[email protected]df1c9862012-02-27 10:37:31414} // namespace ash