jamescook@chromium.org | 9c66adc | 2012-01-05 02:10:16 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
sky@chromium.org | 55de57d | 2012-09-06 04:29:02 | [diff] [blame] | 5 | #include "ash/shell.h" |
| 6 | |
| 7 | #include <algorithm> |
Mitsuru Oshima | 04b54d0 | 2017-10-09 14:22:45 | [diff] [blame] | 8 | #include <memory> |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 9 | #include <queue> |
sky@chromium.org | 55de57d | 2012-09-06 04:29:02 | [diff] [blame] | 10 | #include <vector> |
| 11 | |
varunjain@chromium.org | c086bab | 2013-06-06 21:46:44 | [diff] [blame] | 12 | #include "ash/display/mouse_cursor_event_filter.h" |
| 13 | #include "ash/drag_drop/drag_drop_controller.h" |
James Cook | eb426b5 | 2018-09-17 16:45:12 | [diff] [blame] | 14 | #include "ash/drag_drop/drag_drop_controller_test_api.h" |
Darren Shen | cb250844 | 2019-07-03 21:48:23 | [diff] [blame] | 15 | #include "ash/keyboard/ui/keyboard_ui_controller.h" |
Darren Shen | 50e1495 | 2019-05-14 03:40:43 | [diff] [blame] | 16 | #include "ash/keyboard/ui/keyboard_util.h" |
Xiyuan Xia | 14619a2 | 2019-05-14 20:20:44 | [diff] [blame] | 17 | #include "ash/public/cpp/ash_prefs.h" |
Darren Shen | cd7d584d | 2019-05-15 01:30:35 | [diff] [blame] | 18 | #include "ash/public/cpp/keyboard/keyboard_switches.h" |
jamescook | 8800b823 | 2016-10-19 12:46:27 | [diff] [blame] | 19 | #include "ash/public/cpp/shell_window_ids.h" |
Jun Mukai | 4498638 | 2019-05-14 18:19:20 | [diff] [blame] | 20 | #include "ash/public/cpp/test/shell_test_api.h" |
oshima@chromium.org | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 21 | #include "ash/root_window_controller.h" |
Xiyuan Xia | e7b1954 | 2019-05-06 23:05:18 | [diff] [blame] | 22 | #include "ash/session/session_controller_impl.h" |
James Cook | 346c8c6 | 2017-07-18 19:38:37 | [diff] [blame] | 23 | #include "ash/session/test_session_controller_client.h" |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 24 | #include "ash/shelf/home_button.h" |
James Cook | 840177e | 2017-05-25 02:20:01 | [diff] [blame] | 25 | #include "ash/shelf/shelf.h" |
James Cook | b0bf8e8 | 2017-04-09 17:01:44 | [diff] [blame] | 26 | #include "ash/shelf/shelf_layout_manager.h" |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 27 | #include "ash/shelf/shelf_navigation_widget.h" |
James Cook | b0bf8e8 | 2017-04-09 17:01:44 | [diff] [blame] | 28 | #include "ash/shelf/shelf_widget.h" |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 29 | #include "ash/system/status_area_widget.h" |
ben@chromium.org | 1dd1c1b | 2012-02-17 22:04:47 | [diff] [blame] | 30 | #include "ash/test/ash_test_base.h" |
James Cook | 8532dbc | 2017-07-31 21:54:51 | [diff] [blame] | 31 | #include "ash/test/ash_test_helper.h" |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 32 | #include "ash/test/test_widget_builder.h" |
James Cook | 8532dbc | 2017-07-31 21:54:51 | [diff] [blame] | 33 | #include "ash/test_shell_delegate.h" |
James Cook | b0bf8e8 | 2017-04-09 17:01:44 | [diff] [blame] | 34 | #include "ash/wallpaper/wallpaper_widget_controller.h" |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 35 | #include "ash/wm/desks/desks_util.h" |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 36 | #include "ash/wm/overview/overview_controller.h" |
oka | c21941d | 2017-06-20 17:54:44 | [diff] [blame] | 37 | #include "base/command_line.h" |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 38 | #include "base/containers/flat_set.h" |
avi@chromium.org | a4ea1f1 | 2013-06-07 18:37:07 | [diff] [blame] | 39 | #include "base/strings/utf_string_conversions.h" |
gab | 41aedcb1 | 2016-05-11 17:37:01 | [diff] [blame] | 40 | #include "base/threading/thread_task_runner_handle.h" |
Alexander Alekseev | 3f09a8f | 2018-05-03 02:52:10 | [diff] [blame] | 41 | #include "components/account_id/account_id.h" |
sky@chromium.org | ff027885 | 2013-11-05 22:35:48 | [diff] [blame] | 42 | #include "ui/aura/env.h" |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 43 | #include "ui/aura/window.h" |
ben@chromium.org | fcc51c95 | 2014-02-21 21:31:26 | [diff] [blame] | 44 | #include "ui/aura/window_event_dispatcher.h" |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 45 | #include "ui/base/models/simple_menu_model.h" |
Joel Hockey | 784a832 | 2020-05-20 21:19:25 | [diff] [blame] | 46 | #include "ui/display/scoped_display_for_new_windows.h" |
tapted@chromium.org | 73c9fd0 | 2014-07-28 01:48:52 | [diff] [blame] | 47 | #include "ui/events/test/event_generator.h" |
sadrul@chromium.org | e703dfe | 2013-11-25 21:41:50 | [diff] [blame] | 48 | #include "ui/events/test/events_test_utils.h" |
tdanderson@google.com | cd9f71d | 2014-03-20 21:54:21 | [diff] [blame] | 49 | #include "ui/events/test/test_event_handler.h" |
Avi Drissman | fefc2f8 | 2014-12-22 19:25:29 | [diff] [blame] | 50 | #include "ui/gfx/geometry/size.h" |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 51 | #include "ui/views/controls/menu/menu_controller.h" |
| 52 | #include "ui/views/controls/menu/menu_runner.h" |
tfarina@chromium.org | c13be0d | 2011-11-22 02:09:58 | [diff] [blame] | 53 | #include "ui/views/widget/widget.h" |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 54 | #include "ui/views/widget/widget_delegate.h" |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 55 | #include "ui/views/window/dialog_delegate.h" |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 56 | |
jamescook@chromium.org | 615922f | 2012-02-07 02:41:15 | [diff] [blame] | 57 | using aura::RootWindow; |
| 58 | |
ben@chromium.org | 55f59335 | 2011-12-24 05:42:46 | [diff] [blame] | 59 | namespace ash { |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 60 | |
| 61 | namespace { |
| 62 | |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 63 | aura::Window* GetActiveDeskContainer() { |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 64 | return Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 65 | desks_util::GetActiveDeskContainerId()); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | aura::Window* GetAlwaysOnTopContainer() { |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 69 | return Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
| 70 | kShellWindowId_AlwaysOnTopContainer); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 71 | } |
| 72 | |
jamescook@chromium.org | b0079a9 | 2012-01-25 20:13:38 | [diff] [blame] | 73 | // Expect ALL the containers! |
| 74 | void ExpectAllContainers() { |
ben@chromium.org | bf9cdb36 | 2013-10-25 19:22:45 | [diff] [blame] | 75 | aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 76 | |
| 77 | // Validate no duplicate container IDs. |
| 78 | base::flat_set<int> container_ids; |
| 79 | std::queue<aura::Window*> window_queue; |
| 80 | window_queue.push(root_window); |
| 81 | while (!window_queue.empty()) { |
| 82 | aura::Window* current_window = window_queue.front(); |
| 83 | window_queue.pop(); |
| 84 | for (aura::Window* child : current_window->children()) |
| 85 | window_queue.push(child); |
| 86 | |
Allen Bauer | 6d2399c | 2021-05-13 16:06:25 | [diff] [blame] | 87 | const int id = current_window->GetId(); |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 88 | |
| 89 | // Skip windows with no IDs. |
| 90 | if (id == aura::Window::kInitialId) |
| 91 | continue; |
| 92 | |
| 93 | EXPECT_TRUE(container_ids.insert(id).second) |
| 94 | << "Found duplicate ID: " << id |
| 95 | << " at window: " << current_window->GetName(); |
| 96 | } |
| 97 | |
msw | 607227f8 | 2016-08-30 17:22:39 | [diff] [blame] | 98 | EXPECT_TRUE( |
| 99 | Shell::GetContainer(root_window, kShellWindowId_WallpaperContainer)); |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 100 | |
| 101 | for (int desk_id : desks_util::GetDesksContainersIds()) |
| 102 | EXPECT_TRUE(Shell::GetContainer(root_window, desk_id)); |
| 103 | |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 104 | EXPECT_TRUE( |
| 105 | Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer)); |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 106 | EXPECT_TRUE(Shell::GetContainer(root_window, kShellWindowId_ShelfContainer)); |
| 107 | EXPECT_TRUE( |
| 108 | Shell::GetContainer(root_window, kShellWindowId_SystemModalContainer)); |
msw | 607227f8 | 2016-08-30 17:22:39 | [diff] [blame] | 109 | EXPECT_TRUE(Shell::GetContainer(root_window, |
| 110 | kShellWindowId_LockScreenWallpaperContainer)); |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 111 | EXPECT_TRUE( |
| 112 | Shell::GetContainer(root_window, kShellWindowId_LockScreenContainer)); |
| 113 | EXPECT_TRUE(Shell::GetContainer(root_window, |
| 114 | kShellWindowId_LockSystemModalContainer)); |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 115 | EXPECT_TRUE(Shell::GetContainer(root_window, kShellWindowId_MenuContainer)); |
| 116 | EXPECT_TRUE(Shell::GetContainer(root_window, |
| 117 | kShellWindowId_DragImageAndTooltipContainer)); |
| 118 | EXPECT_TRUE( |
| 119 | Shell::GetContainer(root_window, kShellWindowId_SettingBubbleContainer)); |
| 120 | EXPECT_TRUE( |
| 121 | Shell::GetContainer(root_window, kShellWindowId_OverlayContainer)); |
bshe | c387542 | 2014-09-29 13:21:30 | [diff] [blame] | 122 | EXPECT_TRUE(Shell::GetContainer(root_window, |
| 123 | kShellWindowId_ImeWindowParentContainer)); |
Yuichiro Hanada | 0c5b078 | 2017-12-04 08:05:32 | [diff] [blame] | 124 | EXPECT_TRUE(Shell::GetContainer(root_window, |
| 125 | kShellWindowId_VirtualKeyboardContainer)); |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 126 | EXPECT_TRUE( |
| 127 | Shell::GetContainer(root_window, kShellWindowId_MouseCursorContainer)); |
James Cook | 9793f01d | 2017-08-14 16:56:23 | [diff] [blame] | 128 | |
| 129 | // Phantom window is not a container. |
| 130 | EXPECT_EQ(0u, container_ids.count(kShellWindowId_PhantomWindow)); |
| 131 | EXPECT_FALSE(Shell::GetContainer(root_window, kShellWindowId_PhantomWindow)); |
jamescook@chromium.org | b0079a9 | 2012-01-25 20:13:38 | [diff] [blame] | 132 | } |
| 133 | |
Elly Fong-Jones | bc57599 | 2020-10-02 23:13:18 | [diff] [blame] | 134 | std::unique_ptr<views::WidgetDelegateView> CreateModalWidgetDelegate() { |
Elly Fong-Jones | c5a0df53 | 2020-08-25 12:51:47 | [diff] [blame] | 135 | auto delegate = std::make_unique<views::WidgetDelegateView>(); |
| 136 | delegate->SetCanResize(true); |
| 137 | delegate->SetModalType(ui::MODAL_TYPE_SYSTEM); |
Elly Fong-Jones | bc57599 | 2020-10-02 23:13:18 | [diff] [blame] | 138 | delegate->SetOwnedByWidget(true); |
Jan Wilken Dörrie | c92a6d724 | 2021-03-23 17:43:48 | [diff] [blame] | 139 | delegate->SetTitle(u"Modal Window"); |
Elly Fong-Jones | bc57599 | 2020-10-02 23:13:18 | [diff] [blame] | 140 | return delegate; |
Elly Fong-Jones | c5a0df53 | 2020-08-25 12:51:47 | [diff] [blame] | 141 | } |
James Cook | 43e5034d | 2018-06-01 20:51:17 | [diff] [blame] | 142 | |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 143 | class SimpleMenuDelegate : public ui::SimpleMenuModel::Delegate { |
| 144 | public: |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 145 | SimpleMenuDelegate() = default; |
Peter Boström | ec31a04 | 2021-09-16 23:37:34 | [diff] [blame] | 146 | |
| 147 | SimpleMenuDelegate(const SimpleMenuDelegate&) = delete; |
| 148 | SimpleMenuDelegate& operator=(const SimpleMenuDelegate&) = delete; |
| 149 | |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 150 | ~SimpleMenuDelegate() override = default; |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 151 | |
dcheng | 1f4538e | 2014-10-27 23:57:05 | [diff] [blame] | 152 | bool IsCommandIdChecked(int command_id) const override { return false; } |
| 153 | |
| 154 | bool IsCommandIdEnabled(int command_id) const override { return true; } |
| 155 | |
dcheng | 1f4538e | 2014-10-27 23:57:05 | [diff] [blame] | 156 | void ExecuteCommand(int command_id, int event_flags) override {} |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 157 | }; |
| 158 | |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 159 | } // namespace |
| 160 | |
James Cook | 317781a | 2017-07-18 02:08:06 | [diff] [blame] | 161 | class ShellTest : public AshTestBase { |
erg@chromium.org | a2e6af1 | 2013-01-07 21:40:35 | [diff] [blame] | 162 | public: |
erg@chromium.org | a2e6af1 | 2013-01-07 21:40:35 | [diff] [blame] | 163 | void TestCreateWindow(views::Widget::InitParams::Type type, |
| 164 | bool always_on_top, |
| 165 | aura::Window* expected_container) { |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 166 | TestWidgetBuilder builder; |
Avi Drissman | 9e653328 | 2019-07-17 17:25:12 | [diff] [blame] | 167 | if (always_on_top) |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 168 | builder.SetZOrderLevel(ui::ZOrderLevel::kFloatingWindow); |
| 169 | views::Widget* widget = |
| 170 | builder.SetWidgetType(type).BuildOwnedByNativeWidget(); |
erg@chromium.org | a2e6af1 | 2013-01-07 21:40:35 | [diff] [blame] | 171 | |
| 172 | EXPECT_TRUE( |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 173 | expected_container->Contains(widget->GetNativeWindow()->parent())) |
| 174 | << "TestCreateWindow: type=" << type |
| 175 | << ", always_on_top=" << always_on_top; |
erg@chromium.org | a2e6af1 | 2013-01-07 21:40:35 | [diff] [blame] | 176 | |
| 177 | widget->Close(); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 178 | } |
erg@chromium.org | a2e6af1 | 2013-01-07 21:40:35 | [diff] [blame] | 179 | |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 180 | void LockScreenAndVerifyMenuClosed() { |
| 181 | // Verify a menu is open before locking. |
| 182 | views::MenuController* menu_controller = |
| 183 | views::MenuController::GetActiveInstance(); |
| 184 | DCHECK(menu_controller); |
Hwanseung Lee | 21aaa18d | 2019-04-20 01:14:51 | [diff] [blame] | 185 | EXPECT_EQ(views::MenuController::ExitType::kNone, |
| 186 | menu_controller->exit_type()); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 187 | |
| 188 | // Create a LockScreen window. |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 189 | views::Widget* lock_widget = |
| 190 | TestWidgetBuilder() |
| 191 | .SetWidgetType(views::Widget::InitParams::TYPE_WINDOW) |
| 192 | .SetShow(false) |
| 193 | .BuildOwnedByNativeWidget(); |
msw | bc0a8b48 | 2016-06-30 02:21:14 | [diff] [blame] | 194 | Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
| 195 | kShellWindowId_LockScreenContainer) |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 196 | ->AddChild(lock_widget->GetNativeView()); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 197 | lock_widget->Show(); |
xiyuan | 7ebbf7f | 2017-04-10 16:49:10 | [diff] [blame] | 198 | |
| 199 | // Simulate real screen locker to change session state to LOCKED |
| 200 | // when it is shown. |
Xiyuan Xia | 0418146 | 2019-05-07 22:09:28 | [diff] [blame] | 201 | GetSessionControllerClient()->LockScreen(); |
xiyuan | 7ebbf7f | 2017-04-10 16:49:10 | [diff] [blame] | 202 | |
Xiyuan Xia | 0418146 | 2019-05-07 22:09:28 | [diff] [blame] | 203 | SessionControllerImpl* controller = Shell::Get()->session_controller(); |
xiyuan | f1ff14d | 2017-03-20 20:28:14 | [diff] [blame] | 204 | EXPECT_TRUE(controller->IsScreenLocked()); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 205 | EXPECT_TRUE(lock_widget->GetNativeView()->HasFocus()); |
| 206 | |
| 207 | // Verify menu is closed. |
jonross | 6d38f59 | 2017-03-14 19:34:33 | [diff] [blame] | 208 | EXPECT_EQ(nullptr, views::MenuController::GetActiveInstance()); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 209 | lock_widget->Close(); |
xiyuan | f1ff14d | 2017-03-20 20:28:14 | [diff] [blame] | 210 | GetSessionControllerClient()->UnlockScreen(); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 211 | } |
erg@chromium.org | a2e6af1 | 2013-01-07 21:40:35 | [diff] [blame] | 212 | }; |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 213 | |
| 214 | TEST_F(ShellTest, CreateWindow) { |
| 215 | // Normal window should be created in default container. |
| 216 | TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW, |
| 217 | false, // always_on_top |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 218 | GetActiveDeskContainer()); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 219 | TestCreateWindow(views::Widget::InitParams::TYPE_POPUP, |
| 220 | false, // always_on_top |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 221 | GetActiveDeskContainer()); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 222 | |
| 223 | // Always-on-top window and popup are created in always-on-top container. |
| 224 | TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW, |
| 225 | true, // always_on_top |
| 226 | GetAlwaysOnTopContainer()); |
| 227 | TestCreateWindow(views::Widget::InitParams::TYPE_POPUP, |
| 228 | true, // always_on_top |
| 229 | GetAlwaysOnTopContainer()); |
| 230 | } |
| 231 | |
James Cook | 43e5034d | 2018-06-01 20:51:17 | [diff] [blame] | 232 | // Verifies that a window with a preferred size is created centered on the |
| 233 | // default display for new windows. Mojo apps like shortcut_viewer rely on this |
| 234 | // behavior. |
| 235 | TEST_F(ShellTest, CreateWindowWithPreferredSize) { |
| 236 | UpdateDisplay("1024x768,800x600"); |
| 237 | |
| 238 | aura::Window* secondary_root = Shell::GetAllRootWindows()[1]; |
Joel Hockey | 784a832 | 2020-05-20 21:19:25 | [diff] [blame] | 239 | display::ScopedDisplayForNewWindows scoped_display(secondary_root); |
James Cook | 43e5034d | 2018-06-01 20:51:17 | [diff] [blame] | 240 | |
| 241 | views::Widget::InitParams params; |
| 242 | params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 243 | // Don't specify bounds, parent or context. |
Elly Fong-Jones | c5a0df53 | 2020-08-25 12:51:47 | [diff] [blame] | 244 | { |
| 245 | auto delegate = std::make_unique<views::WidgetDelegateView>(); |
| 246 | delegate->SetPreferredSize(gfx::Size(400, 300)); |
| 247 | params.delegate = delegate.release(); |
| 248 | } |
James Cook | 43e5034d | 2018-06-01 20:51:17 | [diff] [blame] | 249 | views::Widget widget; |
Peter Kasting | 97defc9 | 2020-03-05 18:49:02 | [diff] [blame] | 250 | params.context = GetContext(); |
Ahmed Fakhry | 32f3c45 | 2019-08-01 16:36:34 | [diff] [blame] | 251 | widget.Init(std::move(params)); |
James Cook | 43e5034d | 2018-06-01 20:51:17 | [diff] [blame] | 252 | |
| 253 | // Widget is centered on secondary display. |
| 254 | EXPECT_EQ(secondary_root, widget.GetNativeWindow()->GetRootWindow()); |
| 255 | EXPECT_EQ(GetSecondaryDisplay().work_area().CenterPoint(), |
| 256 | widget.GetRestoredBounds().CenterPoint()); |
| 257 | } |
| 258 | |
Avi Drissman | 9e653328 | 2019-07-17 17:25:12 | [diff] [blame] | 259 | TEST_F(ShellTest, ChangeZOrderLevel) { |
Avi Drissman | 9e653328 | 2019-07-17 17:25:12 | [diff] [blame] | 260 | // Creates a normal window. |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 261 | views::Widget* widget = TestWidgetBuilder().BuildOwnedByNativeWidget(); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 262 | |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 263 | // It should be in the active desk container. |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 264 | EXPECT_TRUE( |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 265 | GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 266 | |
Avi Drissman | 9e653328 | 2019-07-17 17:25:12 | [diff] [blame] | 267 | // Set the z-order to float. |
| 268 | widget->SetZOrderLevel(ui::ZOrderLevel::kFloatingWindow); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 269 | // And it should in always on top container now. |
| 270 | EXPECT_EQ(GetAlwaysOnTopContainer(), widget->GetNativeWindow()->parent()); |
| 271 | |
Avi Drissman | 9e653328 | 2019-07-17 17:25:12 | [diff] [blame] | 272 | // Put the z-order back to normal. |
| 273 | widget->SetZOrderLevel(ui::ZOrderLevel::kNormal); |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 274 | // It should go back to the active desk container. |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 275 | EXPECT_TRUE( |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 276 | GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 277 | |
Avi Drissman | 9e653328 | 2019-07-17 17:25:12 | [diff] [blame] | 278 | // Set the z-order again to the normal value. |
| 279 | widget->SetZOrderLevel(ui::ZOrderLevel::kNormal); |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 280 | // Should have no effect and we are still in the the active desk container. |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 281 | EXPECT_TRUE( |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 282 | GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); |
xiyuan@chromium.org | 488b4204 | 2011-11-15 00:20:18 | [diff] [blame] | 283 | |
| 284 | widget->Close(); |
| 285 | } |
| 286 | |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 287 | TEST_F(ShellTest, CreateModalWindow) { |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 288 | // Create a normal window. |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 289 | views::Widget* widget = TestWidgetBuilder().BuildOwnedByNativeWidget(); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 290 | |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 291 | // It should be in the active desk container. |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 292 | EXPECT_TRUE( |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 293 | GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 294 | |
| 295 | // Create a modal window. |
| 296 | views::Widget* modal_widget = views::Widget::CreateWindowWithParent( |
Elly Fong-Jones | c5a0df53 | 2020-08-25 12:51:47 | [diff] [blame] | 297 | CreateModalWidgetDelegate(), widget->GetNativeView()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 298 | modal_widget->Show(); |
| 299 | |
| 300 | // It should be in modal container. |
oshima@chromium.org | 7b0f750 | 2012-06-11 00:12:39 | [diff] [blame] | 301 | aura::Window* modal_container = Shell::GetContainer( |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 302 | Shell::GetPrimaryRootWindow(), kShellWindowId_SystemModalContainer); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 303 | EXPECT_EQ(modal_container, modal_widget->GetNativeWindow()->parent()); |
| 304 | |
| 305 | modal_widget->Close(); |
| 306 | widget->Close(); |
| 307 | } |
| 308 | |
| 309 | TEST_F(ShellTest, CreateLockScreenModalWindow) { |
Maksim Ivanov | 3f60737e | 2020-11-20 05:08:17 | [diff] [blame] | 310 | // Create a normal window. |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 311 | views::Widget* widget = TestWidgetBuilder().BuildOwnedByNativeWidget(); |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 312 | EXPECT_TRUE(widget->GetNativeView()->HasFocus()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 313 | |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 314 | // It should be in the active desk container. |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 315 | EXPECT_TRUE( |
Ahmed Fakhry | f929d5f | 2019-04-11 02:22:48 | [diff] [blame] | 316 | GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 317 | |
Xiyuan Xia | 0418146 | 2019-05-07 22:09:28 | [diff] [blame] | 318 | GetSessionControllerClient()->LockScreen(); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 319 | // Create a LockScreen window. |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 320 | views::Widget* lock_widget = |
| 321 | TestWidgetBuilder().SetShow(false).BuildOwnedByNativeWidget(); |
msw | bc0a8b48 | 2016-06-30 02:21:14 | [diff] [blame] | 322 | Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
| 323 | kShellWindowId_LockScreenContainer) |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 324 | ->AddChild(lock_widget->GetNativeView()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 325 | lock_widget->Show(); |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 326 | EXPECT_TRUE(lock_widget->GetNativeView()->HasFocus()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 327 | |
| 328 | // It should be in LockScreen container. |
oshima@chromium.org | 7b0f750 | 2012-06-11 00:12:39 | [diff] [blame] | 329 | aura::Window* lock_screen = Shell::GetContainer( |
msw | bc0a8b48 | 2016-06-30 02:21:14 | [diff] [blame] | 330 | Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 331 | EXPECT_EQ(lock_screen, lock_widget->GetNativeWindow()->parent()); |
| 332 | |
| 333 | // Create a modal window with a lock window as parent. |
| 334 | views::Widget* lock_modal_widget = views::Widget::CreateWindowWithParent( |
Elly Fong-Jones | c5a0df53 | 2020-08-25 12:51:47 | [diff] [blame] | 335 | CreateModalWidgetDelegate(), lock_widget->GetNativeView()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 336 | lock_modal_widget->Show(); |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 337 | EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 338 | |
| 339 | // It should be in LockScreen modal container. |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 340 | aura::Window* lock_modal_container = |
| 341 | Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
msw | bc0a8b48 | 2016-06-30 02:21:14 | [diff] [blame] | 342 | kShellWindowId_LockSystemModalContainer); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 343 | EXPECT_EQ(lock_modal_container, |
| 344 | lock_modal_widget->GetNativeWindow()->parent()); |
| 345 | |
| 346 | // Create a modal window with a normal window as parent. |
| 347 | views::Widget* modal_widget = views::Widget::CreateWindowWithParent( |
Elly Fong-Jones | c5a0df53 | 2020-08-25 12:51:47 | [diff] [blame] | 348 | CreateModalWidgetDelegate(), widget->GetNativeView()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 349 | modal_widget->Show(); |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 350 | // Window on lock screen shouldn't lost focus. |
| 351 | EXPECT_FALSE(modal_widget->GetNativeView()->HasFocus()); |
| 352 | EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus()); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 353 | |
| 354 | // It should be in non-LockScreen modal container. |
oshima@chromium.org | 7b0f750 | 2012-06-11 00:12:39 | [diff] [blame] | 355 | aura::Window* modal_container = Shell::GetContainer( |
msw | bc0a8b48 | 2016-06-30 02:21:14 | [diff] [blame] | 356 | Shell::GetPrimaryRootWindow(), kShellWindowId_SystemModalContainer); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 357 | EXPECT_EQ(modal_container, modal_widget->GetNativeWindow()->parent()); |
| 358 | |
Elly Fong-Jones | bc57599 | 2020-10-02 23:13:18 | [diff] [blame] | 359 | // Modal widget without parent, caused crash see crbug.com/226141 |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 360 | views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget( |
Elly Fong-Jones | bc57599 | 2020-10-02 23:13:18 | [diff] [blame] | 361 | CreateModalWidgetDelegate(), GetContext(), nullptr); |
dpolukhin@chromium.org | 71a7571 | 2013-05-30 18:59:24 | [diff] [blame] | 362 | |
| 363 | modal_dialog->Show(); |
| 364 | EXPECT_FALSE(modal_dialog->GetNativeView()->HasFocus()); |
| 365 | EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus()); |
| 366 | |
| 367 | modal_dialog->Close(); |
| 368 | modal_widget->Close(); |
nkostylev@chromium.org | 55bdb50 | 2011-11-29 20:26:25 | [diff] [blame] | 369 | modal_widget->Close(); |
| 370 | lock_modal_widget->Close(); |
| 371 | lock_widget->Close(); |
| 372 | widget->Close(); |
| 373 | } |
| 374 | |
mazda@chromium.org | f7eb89c | 2011-12-13 09:48:54 | [diff] [blame] | 375 | TEST_F(ShellTest, IsScreenLocked) { |
Xiyuan Xia | e7b1954 | 2019-05-06 23:05:18 | [diff] [blame] | 376 | SessionControllerImpl* controller = Shell::Get()->session_controller(); |
Xiyuan Xia | 0418146 | 2019-05-07 22:09:28 | [diff] [blame] | 377 | GetSessionControllerClient()->LockScreen(); |
xiyuan | f1ff14d | 2017-03-20 20:28:14 | [diff] [blame] | 378 | EXPECT_TRUE(controller->IsScreenLocked()); |
| 379 | GetSessionControllerClient()->UnlockScreen(); |
| 380 | EXPECT_FALSE(controller->IsScreenLocked()); |
mazda@chromium.org | f7eb89c | 2011-12-13 09:48:54 | [diff] [blame] | 381 | } |
| 382 | |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 383 | TEST_F(ShellTest, LockScreenClosesActiveMenu) { |
| 384 | SimpleMenuDelegate menu_delegate; |
dcheng | a9454747 | 2016-04-08 08:41:11 | [diff] [blame] | 385 | std::unique_ptr<ui::SimpleMenuModel> menu_model( |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 386 | new ui::SimpleMenuModel(&menu_delegate)); |
Jan Wilken Dörrie | c92a6d724 | 2021-03-23 17:43:48 | [diff] [blame] | 387 | menu_model->AddItem(0, u"Menu item"); |
msw | ad3d955 | 2017-05-18 21:23:36 | [diff] [blame] | 388 | views::Widget* widget = Shell::GetPrimaryRootWindowController() |
msw | 607227f8 | 2016-08-30 17:22:39 | [diff] [blame] | 389 | ->wallpaper_widget_controller() |
Toni Barzic | 71239915 | 2018-02-15 17:38:40 | [diff] [blame] | 390 | ->GetWidget(); |
jonross | 5ab7c2d | 2017-04-21 22:34:31 | [diff] [blame] | 391 | std::unique_ptr<views::MenuRunner> menu_runner( |
| 392 | new views::MenuRunner(menu_model.get(), views::MenuRunner::CONTEXT_MENU)); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 393 | |
Charlene Yan | d29f92a | 2019-04-19 20:45:02 | [diff] [blame] | 394 | menu_runner->RunMenuAt(widget, nullptr, gfx::Rect(), |
Hwanseung Lee | e75bb63 | 2019-03-21 22:55:43 | [diff] [blame] | 395 | views::MenuAnchorPosition::kTopLeft, |
jonross | 5ab7c2d | 2017-04-21 22:34:31 | [diff] [blame] | 396 | ui::MENU_SOURCE_MOUSE); |
jonross | 19c31fa | 2017-03-14 13:33:34 | [diff] [blame] | 397 | LockScreenAndVerifyMenuClosed(); |
flackr@chromium.org | 9c52d5e | 2013-08-20 09:47:03 | [diff] [blame] | 398 | } |
| 399 | |
oshima@chromium.org | 87847948 | 2013-09-18 10:29:19 | [diff] [blame] | 400 | TEST_F(ShellTest, ManagedWindowModeBasics) { |
jamescook@chromium.org | b0079a9 | 2012-01-25 20:13:38 | [diff] [blame] | 401 | // We start with the usual window containers. |
| 402 | ExpectAllContainers(); |
tfarina@chromium.org | 64936bf | 2013-11-14 19:48:36 | [diff] [blame] | 403 | // Shelf is visible. |
jamescook | 577c95b | 2016-08-30 04:03:54 | [diff] [blame] | 404 | ShelfWidget* shelf_widget = GetPrimaryShelf()->shelf_widget(); |
tfarina@chromium.org | 864b5855 | 2013-12-19 04:19:38 | [diff] [blame] | 405 | EXPECT_TRUE(shelf_widget->IsVisible()); |
tfarina@chromium.org | 64936bf | 2013-11-14 19:48:36 | [diff] [blame] | 406 | // Shelf is at bottom-left of screen. |
tfarina@chromium.org | 864b5855 | 2013-12-19 04:19:38 | [diff] [blame] | 407 | EXPECT_EQ(0, shelf_widget->GetWindowBoundsInScreen().x()); |
riajiang | dfdfc99e | 2016-11-29 05:37:47 | [diff] [blame] | 408 | EXPECT_EQ( |
| 409 | Shell::GetPrimaryRootWindow()->GetHost()->GetBoundsInPixels().height(), |
| 410 | shelf_widget->GetWindowBoundsInScreen().bottom()); |
msw | 607227f8 | 2016-08-30 17:22:39 | [diff] [blame] | 411 | // We have a wallpaper but not a bare layer. |
antrim@chromium.org | b4ddc7a | 2012-08-07 04:17:32 | [diff] [blame] | 412 | // TODO (antrim): enable once we find out why it fails component build. |
msw | 607227f8 | 2016-08-30 17:22:39 | [diff] [blame] | 413 | // WallpaperWidgetController* wallpaper = |
antrim@chromium.org | b4ddc7a | 2012-08-07 04:17:32 | [diff] [blame] | 414 | // Shell::GetPrimaryRootWindow()-> |
oshima@chromium.org | 093b8d64 | 2014-04-03 20:59:28 | [diff] [blame] | 415 | // GetProperty(kWindowDesktopComponent); |
msw | 607227f8 | 2016-08-30 17:22:39 | [diff] [blame] | 416 | // EXPECT_TRUE(wallpaper); |
| 417 | // EXPECT_TRUE(wallpaper->widget()); |
| 418 | // EXPECT_FALSE(wallpaper->layer()); |
jamescook@chromium.org | b0079a9 | 2012-01-25 20:13:38 | [diff] [blame] | 419 | |
| 420 | // Create a normal window. It is not maximized. |
Mitsuru Oshima | 0c59d07 | 2021-01-13 17:53:58 | [diff] [blame] | 421 | views::Widget* widget = TestWidgetBuilder() |
| 422 | .SetBounds(gfx::Rect(11, 22, 300, 400)) |
| 423 | .BuildOwnedByNativeWidget(); |
jamescook@chromium.org | b0079a9 | 2012-01-25 20:13:38 | [diff] [blame] | 424 | EXPECT_FALSE(widget->IsMaximized()); |
| 425 | |
jamescook@chromium.org | b0079a9 | 2012-01-25 20:13:38 | [diff] [blame] | 426 | // Clean up. |
| 427 | widget->Close(); |
| 428 | } |
| 429 | |
sadrul@chromium.org | d10f5ae3 | 2014-03-12 00:29:58 | [diff] [blame] | 430 | // Tests that the cursor-filter is ahead of the drag-drop controller in the |
| 431 | // pre-target list. |
varunjain@chromium.org | c086bab | 2013-06-06 21:46:44 | [diff] [blame] | 432 | TEST_F(ShellTest, TestPreTargetHandlerOrder) { |
sky | cb4be5b | 2017-04-06 17:52:45 | [diff] [blame] | 433 | Shell* shell = Shell::Get(); |
sadrul@chromium.org | e703dfe | 2013-11-25 21:41:50 | [diff] [blame] | 434 | ui::EventTargetTestApi test_api(shell); |
Jun Mukai | 4498638 | 2019-05-14 18:19:20 | [diff] [blame] | 435 | ShellTestApi shell_test_api; |
varunjain@chromium.org | c086bab | 2013-06-06 21:46:44 | [diff] [blame] | 436 | |
Katie D | b68a552 | 2018-03-30 18:47:36 | [diff] [blame] | 437 | ui::EventHandlerList handlers = test_api.GetPreTargetHandlers(); |
sadrul@chromium.org | d10f5ae3 | 2014-03-12 00:29:58 | [diff] [blame] | 438 | ui::EventHandlerList::const_iterator cursor_filter = |
| 439 | std::find(handlers.begin(), handlers.end(), shell->mouse_cursor_filter()); |
jamescook | b8dcef52 | 2016-06-25 14:42:55 | [diff] [blame] | 440 | ui::EventHandlerList::const_iterator drag_drop = std::find( |
| 441 | handlers.begin(), handlers.end(), shell_test_api.drag_drop_controller()); |
sadrul@chromium.org | d10f5ae3 | 2014-03-12 00:29:58 | [diff] [blame] | 442 | EXPECT_NE(handlers.end(), cursor_filter); |
| 443 | EXPECT_NE(handlers.end(), drag_drop); |
| 444 | EXPECT_GT(drag_drop, cursor_filter); |
varunjain@chromium.org | c086bab | 2013-06-06 21:46:44 | [diff] [blame] | 445 | } |
| 446 | |
sky@chromium.org | ff027885 | 2013-11-05 22:35:48 | [diff] [blame] | 447 | // Verifies an EventHandler added to Env gets notified from EventGenerator. |
| 448 | TEST_F(ShellTest, EnvPreTargetHandler) { |
tdanderson@google.com | cd9f71d | 2014-03-20 21:54:21 | [diff] [blame] | 449 | ui::test::TestEventHandler event_handler; |
Jun Mukai | c3b5929 | 2019-05-19 20:44:04 | [diff] [blame] | 450 | aura::Env::GetInstance()->AddPreTargetHandler(&event_handler); |
tapted@chromium.org | 73c9fd0 | 2014-07-28 01:48:52 | [diff] [blame] | 451 | ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); |
sky@chromium.org | ff027885 | 2013-11-05 22:35:48 | [diff] [blame] | 452 | generator.MoveMouseBy(1, 1); |
| 453 | EXPECT_NE(0, event_handler.num_mouse_events()); |
Jun Mukai | c3b5929 | 2019-05-19 20:44:04 | [diff] [blame] | 454 | aura::Env::GetInstance()->RemovePreTargetHandler(&event_handler); |
sky@chromium.org | ff027885 | 2013-11-05 22:35:48 | [diff] [blame] | 455 | } |
| 456 | |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 457 | // Verifies that pressing tab on an empty shell (one with no windows visible) |
| 458 | // will put focus on the shelf. This enables keyboard only users to get to the |
| 459 | // shelf without knowing the more obscure accelerators. Tab should move focus to |
| 460 | // the home button, shift + tab to the status widget. From there, normal shelf |
| 461 | // tab behaviour takes over, and the shell no longer catches that event. |
| 462 | TEST_F(ShellTest, NoWindowTabFocus) { |
| 463 | ExpectAllContainers(); |
| 464 | |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 465 | StatusAreaWidget* status_area_widget = |
| 466 | GetPrimaryShelf()->status_area_widget(); |
| 467 | ShelfNavigationWidget* home_button = GetPrimaryShelf()->navigation_widget(); |
| 468 | |
| 469 | // Create a normal window. It is not maximized. |
| 470 | auto widget = CreateTestWidget(); |
| 471 | |
| 472 | // Hit tab with window open, and expect that focus is not on the navigation |
| 473 | // widget or status widget. |
James Cook | c275bd6 | 2021-07-20 00:32:21 | [diff] [blame] | 474 | PressAndReleaseKey(ui::VKEY_TAB); |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 475 | EXPECT_FALSE(home_button->GetNativeView()->HasFocus()); |
| 476 | EXPECT_FALSE(status_area_widget->GetNativeView()->HasFocus()); |
| 477 | |
| 478 | // Minimize the window, hit tab and expect that focus is on the launcher. |
| 479 | widget->Minimize(); |
James Cook | c275bd6 | 2021-07-20 00:32:21 | [diff] [blame] | 480 | PressAndReleaseKey(ui::VKEY_TAB); |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 481 | EXPECT_TRUE(home_button->GetNativeView()->HasFocus()); |
| 482 | |
| 483 | // Show (to steal focus back before continuing testing) and close the window. |
| 484 | widget->Show(); |
| 485 | widget->Close(); |
| 486 | EXPECT_FALSE(home_button->GetNativeView()->HasFocus()); |
| 487 | |
| 488 | // Confirm that pressing tab when overview mode is open does not go to home |
| 489 | // button. Tab should be handled by overview mode and not hit the shell event |
| 490 | // handler. |
minch | 38d1e59 | 2021-07-02 19:30:25 | [diff] [blame] | 491 | EnterOverview(); |
James Cook | c275bd6 | 2021-07-20 00:32:21 | [diff] [blame] | 492 | PressAndReleaseKey(ui::VKEY_TAB); |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 493 | EXPECT_FALSE(home_button->GetNativeView()->HasFocus()); |
minch | 38d1e59 | 2021-07-02 19:30:25 | [diff] [blame] | 494 | ExitOverview(); |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 495 | |
| 496 | // Hit shift tab and expect that focus is on status widget. |
James Cook | c275bd6 | 2021-07-20 00:32:21 | [diff] [blame] | 497 | PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN); |
Angus L. M. McLean IV | aa6378e | 2020-09-30 18:52:20 | [diff] [blame] | 498 | EXPECT_TRUE(status_area_widget->GetNativeView()->HasFocus()); |
| 499 | } |
| 500 | |
sky@chromium.org | 5924a0b | 2012-04-27 17:02:28 | [diff] [blame] | 501 | // This verifies WindowObservers are removed when a window is destroyed after |
| 502 | // the Shell is destroyed. This scenario (aura::Windows being deleted after the |
| 503 | // Shell) occurs if someone is holding a reference to an unparented Window, as |
| 504 | // is the case with a RenderWidgetHostViewAura that isn't on screen. As long as |
| 505 | // everything is ok, we won't crash. If there is a bug, window's destructor will |
| 506 | // notify some deleted object (say VideoDetector or ActivationController) and |
| 507 | // this will crash. |
James Cook | 317781a | 2017-07-18 02:08:06 | [diff] [blame] | 508 | class ShellTest2 : public AshTestBase { |
sky@chromium.org | 5924a0b | 2012-04-27 17:02:28 | [diff] [blame] | 509 | public: |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 510 | ShellTest2() = default; |
Peter Boström | ec31a04 | 2021-09-16 23:37:34 | [diff] [blame] | 511 | |
| 512 | ShellTest2(const ShellTest2&) = delete; |
| 513 | ShellTest2& operator=(const ShellTest2&) = delete; |
| 514 | |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 515 | ~ShellTest2() override = default; |
sky@chromium.org | 5924a0b | 2012-04-27 17:02:28 | [diff] [blame] | 516 | |
| 517 | protected: |
dcheng | a9454747 | 2016-04-08 08:41:11 | [diff] [blame] | 518 | std::unique_ptr<aura::Window> window_; |
sky@chromium.org | 5924a0b | 2012-04-27 17:02:28 | [diff] [blame] | 519 | }; |
| 520 | |
| 521 | TEST_F(ShellTest2, DontCrashWhenWindowDeleted) { |
Jun Mukai | 4e4adb1 | 2019-05-17 16:46:46 | [diff] [blame] | 522 | window_ = std::make_unique<aura::Window>(nullptr, |
| 523 | aura::client::WINDOW_TYPE_UNKNOWN); |
danakj | b161836d | 2015-04-03 05:14:18 | [diff] [blame] | 524 | window_->Init(ui::LAYER_NOT_DRAWN); |
sky@chromium.org | 5924a0b | 2012-04-27 17:02:28 | [diff] [blame] | 525 | } |
| 526 | |
James Cook | eb426b5 | 2018-09-17 16:45:12 | [diff] [blame] | 527 | using ShellLoginTest = NoSessionAshTestBase; |
| 528 | |
| 529 | TEST_F(ShellLoginTest, DragAndDropDisabledBeforeLogin) { |
| 530 | DragDropController* drag_drop_controller = |
Jun Mukai | 4498638 | 2019-05-14 18:19:20 | [diff] [blame] | 531 | ShellTestApi().drag_drop_controller(); |
James Cook | eb426b5 | 2018-09-17 16:45:12 | [diff] [blame] | 532 | DragDropControllerTestApi drag_drop_controller_test_api(drag_drop_controller); |
| 533 | EXPECT_FALSE(drag_drop_controller_test_api.enabled()); |
| 534 | |
| 535 | SimulateUserLogin("user1@test.com"); |
| 536 | EXPECT_TRUE(drag_drop_controller_test_api.enabled()); |
| 537 | } |
| 538 | |
Ahmed Fakhry | e4a2c87 | 2020-01-30 22:34:42 | [diff] [blame] | 539 | using NoDuplicateShellContainerIdsTest = AshTestBase; |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 540 | |
Ahmed Fakhry | e4a2c87 | 2020-01-30 22:34:42 | [diff] [blame] | 541 | TEST_F(NoDuplicateShellContainerIdsTest, ValidateContainersIds) { |
Ahmed Fakhry | 6b034bd | 2019-04-22 15:16:12 | [diff] [blame] | 542 | ExpectAllContainers(); |
| 543 | } |
| 544 | |
ben@chromium.org | 55f59335 | 2011-12-24 05:42:46 | [diff] [blame] | 545 | } // namespace ash |