[go: nahoru, domu]

blob: 183e4c23b90fc2c12f0fc2db7b29e6308d49e107 [file] [log] [blame]
Avi Drissman3a215d1e2022-09-07 19:43:091// Copyright 2012 The Chromium Authors
ben@chromium.org80373572012-01-06 23:14:302// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
ben@chromium.orgee3ed102014-03-11 22:02:015#include "ui/wm/core/window_modality_controller.h"
ben@chromium.org7a8cbb362012-02-21 16:35:516#include "ash/shell.h"
ben@chromium.org1dd1c1b2012-02-17 22:04:477#include "ash/test/ash_test_base.h"
Sammie Quon41837472023-11-16 18:15:538#include "ash/wm/test/test_child_modal_parent.h"
ben@chromium.org80373572012-01-06 23:14:309#include "ash/wm/window_util.h"
10#include "ui/aura/client/aura_constants.h"
xdai74ce23c2016-02-09 20:36:2911#include "ui/aura/client/capture_client.h"
ben@chromium.org80373572012-01-06 23:14:3012#include "ui/aura/test/test_window_delegate.h"
tfarina@chromium.org0477e8e62012-02-27 12:05:2913#include "ui/aura/test/test_windows.h"
ben@chromium.org80373572012-01-06 23:14:3014#include "ui/aura/window.h"
ben@chromium.orgfcc51c952014-02-21 21:31:2615#include "ui/aura/window_event_dispatcher.h"
ben@chromium.org80373572012-01-06 23:14:3016#include "ui/base/ui_base_types.h"
tapted@chromium.org73c9fd02014-07-28 01:48:5217#include "ui/events/test/event_generator.h"
ben@chromium.org0c2dc012012-12-02 00:00:2318#include "ui/views/test/capture_tracking_view.h"
sky@chromium.org150c02e2012-04-27 22:55:4019#include "ui/views/widget/widget.h"
ben@chromium.orgee3ed102014-03-11 22:02:0120#include "ui/wm/core/window_util.h"
ben@chromium.org80373572012-01-06 23:14:3021
22namespace ash {
ben@chromium.org80373572012-01-06 23:14:3023
James Cook317781a2017-07-18 02:08:0624using WindowModalityControllerTest = AshTestBase;
ben@chromium.org80373572012-01-06 23:14:3025
26namespace {
27
28bool ValidateStacking(aura::Window* parent, int ids[], int count) {
29 for (int i = 0; i < count; ++i) {
Allen Bauer6d2399c2021-05-13 16:06:2530 if (parent->children().at(i)->GetId() != ids[i])
ben@chromium.org80373572012-01-06 23:14:3031 return false;
32 }
33 return true;
34}
35
tfarina@chromium.org0477e8e62012-02-27 12:05:2936} // namespace
ben@chromium.org80373572012-01-06 23:14:3037
38// Creates three windows, w1, w11, and w12. w11 is a non-modal transient, w12 is
39// a modal transient.
40// Validates:
41// - it should be possible to activate w12 even when w11 is open.
42// - activating w1 activates w12 and updates stacking order appropriately.
ivankr@chromium.orgea6fb6b2012-01-31 00:37:0343// - closing a window passes focus up the stack.
ben@chromium.org80373572012-01-06 23:14:3044TEST_F(WindowModalityControllerTest, BasicActivation) {
45 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:1146 std::unique_ptr<aura::Window> w1(
erg@chromium.org5ebe6102012-11-28 21:00:0347 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:1148 std::unique_ptr<aura::Window> w11(
erg@chromium.org5ebe6102012-11-28 21:00:0349 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect()));
dchenga94547472016-04-08 08:41:1150 std::unique_ptr<aura::Window> w12(
erg@chromium.org5ebe6102012-11-28 21:00:0351 CreateTestWindowInShellWithDelegate(&d, -12, gfx::Rect()));
ben@chromium.org80373572012-01-06 23:14:3052
ben@chromium.orge319c7e2014-03-14 19:56:1453 ::wm::AddTransientChild(w1.get(), w11.get());
tfarina@chromium.org0477e8e62012-02-27 12:05:2954 wm::ActivateWindow(w1.get());
55 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
56 wm::ActivateWindow(w11.get());
57 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
ben@chromium.org80373572012-01-06 23:14:3058
benrg@chromium.org36e41512012-02-11 00:29:1859 w12->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
ben@chromium.orge319c7e2014-03-14 19:56:1460 ::wm::AddTransientChild(w1.get(), w12.get());
tfarina@chromium.org0477e8e62012-02-27 12:05:2961 wm::ActivateWindow(w12.get());
62 EXPECT_TRUE(wm::IsActiveWindow(w12.get()));
ben@chromium.org80373572012-01-06 23:14:3063
tfarina@chromium.org0477e8e62012-02-27 12:05:2964 wm::ActivateWindow(w11.get());
65 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
ben@chromium.org80373572012-01-06 23:14:3066
jamescookb8dcef522016-06-25 14:42:5567 int check1[] = {-1, -12, -11};
Daniel Chenga020cd72022-02-26 09:23:5368 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
ben@chromium.org80373572012-01-06 23:14:3069
tfarina@chromium.org0477e8e62012-02-27 12:05:2970 wm::ActivateWindow(w1.get());
71 EXPECT_TRUE(wm::IsActiveWindow(w12.get()));
ben@chromium.org80373572012-01-06 23:14:3072 // Transient children are always stacked above their transient parent, which
73 // is why this order is not -11, -1, -12.
jamescookb8dcef522016-06-25 14:42:5574 int check2[] = {-1, -11, -12};
Daniel Chenga020cd72022-02-26 09:23:5375 EXPECT_TRUE(ValidateStacking(w1->parent(), check2, std::size(check2)));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:0376
77 w12.reset();
tfarina@chromium.org0477e8e62012-02-27 12:05:2978 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:0379 w11.reset();
tfarina@chromium.org0477e8e62012-02-27 12:05:2980 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
ben@chromium.org80373572012-01-06 23:14:3081}
82
83// Create two toplevel windows w1 and w2, and nest two modals w11 and w111 below
84// w1.
85// Validates:
86// - activating w1 while w11/w111 is showing always activates most deeply nested
87// descendant.
ivankr@chromium.orgea6fb6b2012-01-31 00:37:0388// - closing a window passes focus up the stack.
ben@chromium.org80373572012-01-06 23:14:3089TEST_F(WindowModalityControllerTest, NestedModals) {
90 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:1191 std::unique_ptr<aura::Window> w1(
erg@chromium.org5ebe6102012-11-28 21:00:0392 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:1193 std::unique_ptr<aura::Window> w11(
erg@chromium.org5ebe6102012-11-28 21:00:0394 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect()));
dchenga94547472016-04-08 08:41:1195 std::unique_ptr<aura::Window> w111(
erg@chromium.org5ebe6102012-11-28 21:00:0396 CreateTestWindowInShellWithDelegate(&d, -111, gfx::Rect()));
dchenga94547472016-04-08 08:41:1197 std::unique_ptr<aura::Window> w2(
erg@chromium.org5ebe6102012-11-28 21:00:0398 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
ben@chromium.org80373572012-01-06 23:14:3099
ben@chromium.orge319c7e2014-03-14 19:56:14100 ::wm::AddTransientChild(w1.get(), w11.get());
101 ::wm::AddTransientChild(w11.get(), w111.get());
ben@chromium.org80373572012-01-06 23:14:30102
tfarina@chromium.org0477e8e62012-02-27 12:05:29103 wm::ActivateWindow(w1.get());
104 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
105 wm::ActivateWindow(w2.get());
106 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
ben@chromium.org80373572012-01-06 23:14:30107
108 // Set up modality.
benrg@chromium.org36e41512012-02-11 00:29:18109 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
110 w111->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
ben@chromium.org80373572012-01-06 23:14:30111
tfarina@chromium.org0477e8e62012-02-27 12:05:29112 wm::ActivateWindow(w1.get());
113 EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
jamescookb8dcef522016-06-25 14:42:55114 int check1[] = {-2, -1, -11, -111};
Daniel Chenga020cd72022-02-26 09:23:53115 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
ben@chromium.org80373572012-01-06 23:14:30116
tfarina@chromium.org0477e8e62012-02-27 12:05:29117 wm::ActivateWindow(w11.get());
118 EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
Daniel Chenga020cd72022-02-26 09:23:53119 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
ben@chromium.org80373572012-01-06 23:14:30120
tfarina@chromium.org0477e8e62012-02-27 12:05:29121 wm::ActivateWindow(w111.get());
122 EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
Daniel Chenga020cd72022-02-26 09:23:53123 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
ben@chromium.org80373572012-01-06 23:14:30124
tfarina@chromium.org0477e8e62012-02-27 12:05:29125 wm::ActivateWindow(w2.get());
126 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
jamescookb8dcef522016-06-25 14:42:55127 int check2[] = {-1, -11, -111, -2};
Daniel Chenga020cd72022-02-26 09:23:53128 EXPECT_TRUE(ValidateStacking(w1->parent(), check2, std::size(check2)));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03129
130 w2.reset();
tfarina@chromium.org0477e8e62012-02-27 12:05:29131 EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03132 w111.reset();
tfarina@chromium.org0477e8e62012-02-27 12:05:29133 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03134 w11.reset();
tfarina@chromium.org0477e8e62012-02-27 12:05:29135 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03136}
137
138// Create two toplevel windows w1 and w2, and nest two modals w11 and w111 below
139// w1.
140// Validates:
141// - destroying w11 while w111 is focused activates w1.
142TEST_F(WindowModalityControllerTest, NestedModalsOuterClosed) {
143 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11144 std::unique_ptr<aura::Window> w1(
erg@chromium.org5ebe6102012-11-28 21:00:03145 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:11146 std::unique_ptr<aura::Window> w11(
erg@chromium.org5ebe6102012-11-28 21:00:03147 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03148 // |w111| will be owned and deleted by |w11|.
149 aura::Window* w111 =
erg@chromium.org5ebe6102012-11-28 21:00:03150 CreateTestWindowInShellWithDelegate(&d, -111, gfx::Rect());
dchenga94547472016-04-08 08:41:11151 std::unique_ptr<aura::Window> w2(
erg@chromium.org5ebe6102012-11-28 21:00:03152 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03153
ben@chromium.orge319c7e2014-03-14 19:56:14154 ::wm::AddTransientChild(w1.get(), w11.get());
155 ::wm::AddTransientChild(w11.get(), w111);
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03156
tfarina@chromium.org0477e8e62012-02-27 12:05:29157 wm::ActivateWindow(w1.get());
158 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
159 wm::ActivateWindow(w2.get());
160 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03161
162 // Set up modality.
benrg@chromium.org36e41512012-02-11 00:29:18163 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
164 w111->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03165
tfarina@chromium.org0477e8e62012-02-27 12:05:29166 wm::ActivateWindow(w1.get());
167 EXPECT_TRUE(wm::IsActiveWindow(w111));
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03168
oshima@chromium.orga278e2602012-02-16 16:46:35169 w111->Hide();
tfarina@chromium.org0477e8e62012-02-27 12:05:29170 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
oshima@chromium.orga278e2602012-02-16 16:46:35171
172 // TODO(oshima): Re-showing doesn't set the focus back to
173 // modal window. There is no such use case right now, but it
174 // probably should.
175
ivankr@chromium.orgea6fb6b2012-01-31 00:37:03176 w11.reset();
tfarina@chromium.org0477e8e62012-02-27 12:05:29177 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
ben@chromium.org80373572012-01-06 23:14:30178}
179
180// Modality also prevents events from being passed to the transient parent.
181TEST_F(WindowModalityControllerTest, Events) {
182 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11183 std::unique_ptr<aura::Window> w1(
184 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect(0, 0, 100, 100)));
185 std::unique_ptr<aura::Window> w11(
186 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect(20, 20, 50, 50)));
187 std::unique_ptr<aura::Window> w111(
calamity8bc4d57e2015-06-11 04:48:04188 CreateTestWindowInShellWithDelegate(&d, -111, gfx::Rect(20, 20, 50, 50)));
ben@chromium.org80373572012-01-06 23:14:30189
ben@chromium.orge319c7e2014-03-14 19:56:14190 ::wm::AddTransientChild(w1.get(), w11.get());
ben@chromium.org80373572012-01-06 23:14:30191
calamity8bc4d57e2015-06-11 04:48:04192 // Add a non-modal child to the modal window in order to ensure modality still
193 // works in this case. This is a regression test for https://crbug.com/456697.
194 ::wm::AddTransientChild(w11.get(), w111.get());
195
ben@chromium.org80373572012-01-06 23:14:30196 {
197 // Clicking a point within w1 should activate that window.
tapted@chromium.org73c9fd02014-07-28 01:48:52198 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
199 gfx::Point(10, 10));
ben@chromium.org80373572012-01-06 23:14:30200 generator.ClickLeftButton();
tfarina@chromium.org0477e8e62012-02-27 12:05:29201 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
ben@chromium.org80373572012-01-06 23:14:30202 }
203
benrg@chromium.org36e41512012-02-11 00:29:18204 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
ben@chromium.org80373572012-01-06 23:14:30205
206 {
207 // Clicking a point within w1 should activate w11.
tapted@chromium.org73c9fd02014-07-28 01:48:52208 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
209 gfx::Point(10, 10));
ben@chromium.org80373572012-01-06 23:14:30210 generator.ClickLeftButton();
tfarina@chromium.org0477e8e62012-02-27 12:05:29211 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
ben@chromium.org80373572012-01-06 23:14:30212 }
213}
214
zelidrag@chromium.orgca5e056c2014-04-26 02:10:35215// Events on modal parent activate.
216TEST_F(WindowModalityControllerTest, EventsForEclipsedWindows) {
217 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11218 std::unique_ptr<aura::Window> w1(
219 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect(0, 0, 100, 100)));
220 std::unique_ptr<aura::Window> w11(
221 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect(20, 20, 50, 50)));
zelidrag@chromium.orgca5e056c2014-04-26 02:10:35222 ::wm::AddTransientChild(w1.get(), w11.get());
dchenga94547472016-04-08 08:41:11223 std::unique_ptr<aura::Window> w2(
224 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect(0, 0, 50, 50)));
zelidrag@chromium.orgca5e056c2014-04-26 02:10:35225
226 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
227
228 // Partially eclipse w1 with w2.
229 wm::ActivateWindow(w2.get());
230 {
231 // Clicking a point on w1 that is not eclipsed by w2.
tapted@chromium.org73c9fd02014-07-28 01:48:52232 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
233 gfx::Point(90, 90));
zelidrag@chromium.orgca5e056c2014-04-26 02:10:35234 generator.ClickLeftButton();
235 EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
236 }
237}
238
stevenjb@chromium.org0d9334b2012-03-14 04:52:28239// Creates windows w1 and non activatiable child w11. Creates transient window
240// w2 and adds it as a transeint child of w1. Ensures that w2 is parented to
rouslan@chromium.org31d82f42012-11-28 16:48:21241// the parent of w1, and that GetModalTransient(w11) returns w2.
242TEST_F(WindowModalityControllerTest, GetModalTransient) {
stevenjb@chromium.org0d9334b2012-03-14 04:52:28243 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11244 std::unique_ptr<aura::Window> w1(
erg@chromium.org5ebe6102012-11-28 21:00:03245 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:11246 std::unique_ptr<aura::Window> w11(
stevenjb@chromium.org0d9334b2012-03-14 04:52:28247 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get()));
dchenga94547472016-04-08 08:41:11248 std::unique_ptr<aura::Window> w2(
erg@chromium.org5ebe6102012-11-28 21:00:03249 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
stevenjb@chromium.org0d9334b2012-03-14 04:52:28250 w2->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
251
252 aura::Window* wt;
ben@chromium.orge319c7e2014-03-14 19:56:14253 wt = ::wm::GetModalTransient(w1.get());
Mike Wasserman16f95212018-07-04 00:55:50254 ASSERT_EQ(nullptr, wt);
stevenjb@chromium.org0d9334b2012-03-14 04:52:28255
256 // Parent w2 to w1. It should get parented to the parent of w1.
ben@chromium.orge319c7e2014-03-14 19:56:14257 ::wm::AddTransientChild(w1.get(), w2.get());
stevenjb@chromium.org0d9334b2012-03-14 04:52:28258 ASSERT_EQ(2U, w1->parent()->children().size());
Allen Bauer6d2399c2021-05-13 16:06:25259 EXPECT_EQ(-2, w1->parent()->children().at(1)->GetId());
stevenjb@chromium.org0d9334b2012-03-14 04:52:28260
261 // Request the modal transient window for w1, it should be w2.
ben@chromium.orge319c7e2014-03-14 19:56:14262 wt = ::wm::GetModalTransient(w1.get());
Mike Wasserman16f95212018-07-04 00:55:50263 ASSERT_NE(nullptr, wt);
Allen Bauer6d2399c2021-05-13 16:06:25264 EXPECT_EQ(-2, wt->GetId());
stevenjb@chromium.org0d9334b2012-03-14 04:52:28265
266 // Request the modal transient window for w11, it should also be w2.
ben@chromium.orge319c7e2014-03-14 19:56:14267 wt = ::wm::GetModalTransient(w11.get());
Mike Wasserman16f95212018-07-04 00:55:50268 ASSERT_NE(nullptr, wt);
Allen Bauer6d2399c2021-05-13 16:06:25269 EXPECT_EQ(-2, wt->GetId());
stevenjb@chromium.org0d9334b2012-03-14 04:52:28270}
271
sky@chromium.org150c02e2012-04-27 22:55:40272// Verifies we generate a capture lost when showing a modal window.
273TEST_F(WindowModalityControllerTest, ChangeCapture) {
erg@chromium.org6e392062012-12-12 20:45:42274 views::Widget* widget = views::Widget::CreateWindowWithContext(
Peter Kastingac8ec152020-03-05 01:05:50275 nullptr, Shell::GetPrimaryRootWindow(), gfx::Rect(0, 0, 200, 200));
dchenga94547472016-04-08 08:41:11276 std::unique_ptr<aura::Window> widget_window(widget->GetNativeView());
ben@chromium.org0c2dc012012-12-02 00:00:23277 views::test::CaptureTrackingView* view = new views::test::CaptureTrackingView;
sky@chromium.org150c02e2012-04-27 22:55:40278 widget->client_view()->AddChildView(view);
sky@chromium.org150c02e2012-04-27 22:55:40279 view->SetBoundsRect(widget->client_view()->GetLocalBounds());
280 widget->Show();
281
282 gfx::Point center(view->width() / 2, view->height() / 2);
283 views::View::ConvertPointToScreen(view, &center);
tapted@chromium.org73c9fd02014-07-28 01:48:52284 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), center);
sky@chromium.org150c02e2012-04-27 22:55:40285 generator.PressLeftButton();
286 EXPECT_TRUE(view->got_press());
287
Peter Kastingac8ec152020-03-05 01:05:50288 views::Widget* modal_widget = views::Widget::CreateWindowWithParent(
289 nullptr, widget->GetNativeView(), gfx::Rect(50, 50, 200, 200));
dchenga94547472016-04-08 08:41:11290 std::unique_ptr<aura::Window> modal_window(modal_widget->GetNativeView());
sky@chromium.org150c02e2012-04-27 22:55:40291 modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
ben@chromium.org0c2dc012012-12-02 00:00:23292 views::test::CaptureTrackingView* modal_view =
293 new views::test::CaptureTrackingView;
sky@chromium.org150c02e2012-04-27 22:55:40294 modal_widget->client_view()->AddChildView(modal_view);
sky@chromium.org150c02e2012-04-27 22:55:40295 modal_view->SetBoundsRect(modal_widget->client_view()->GetLocalBounds());
296 modal_widget->Show();
297
298 EXPECT_TRUE(view->got_capture_lost());
299 generator.ReleaseLeftButton();
300
301 view->reset();
302
303 EXPECT_FALSE(modal_view->got_capture_lost());
304 EXPECT_FALSE(modal_view->got_press());
305
306 gfx::Point modal_center(modal_view->width() / 2, modal_view->height() / 2);
307 views::View::ConvertPointToScreen(modal_view, &modal_center);
308 generator.MoveMouseTo(modal_center, 1);
309 generator.PressLeftButton();
310 EXPECT_TRUE(modal_view->got_press());
311 EXPECT_FALSE(modal_view->got_capture_lost());
312 EXPECT_FALSE(view->got_capture_lost());
313 EXPECT_FALSE(view->got_press());
314}
315
xdai74ce23c2016-02-09 20:36:29316// Test that when a child modal window becomes visible, we only release the
317// capture window if the current capture window is in the hierarchy of the child
318// modal window's modal parent window.
319TEST_F(WindowModalityControllerTest, ReleaseCapture) {
Julien Brianceau293917a2017-08-01 17:32:59320 // Create a window hierarchy like this:
robert.bradford9f937f52016-07-18 17:30:48321 // _______________w0______________
322 // | | |
323 // w1 <------ w3 w2
xdai74ce23c2016-02-09 20:36:29324 // | (modal to)
325 // w11
326
327 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11328 std::unique_ptr<aura::Window> w1(
xdai74ce23c2016-02-09 20:36:29329 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:11330 std::unique_ptr<aura::Window> w11(
xdai74ce23c2016-02-09 20:36:29331 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get()));
dchenga94547472016-04-08 08:41:11332 std::unique_ptr<aura::Window> w2(
xdai74ce23c2016-02-09 20:36:29333 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
dchenga94547472016-04-08 08:41:11334 std::unique_ptr<aura::Window> w3(
xdai74ce23c2016-02-09 20:36:29335 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
336 w3->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_CHILD);
337 ::wm::SetModalParent(w3.get(), w1.get());
338
339 // w1's capture should be released when w3 becomes visible.
340 w3->Hide();
341 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
342 ->SetCapture(w1.get());
343 EXPECT_EQ(w1.get(),
344 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
345 ->GetGlobalCaptureWindow());
346 w3->Show();
347 EXPECT_NE(w1.get(),
348 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
349 ->GetGlobalCaptureWindow());
350
351 // w11's capture should be released when w3 becomes visible.
352 w3->Hide();
353 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
354 ->SetCapture(w11.get());
355 EXPECT_EQ(w11.get(),
356 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
357 ->GetGlobalCaptureWindow());
358 w3->Show();
359 EXPECT_NE(w11.get(),
360 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
361 ->GetGlobalCaptureWindow());
362
363 // w2's capture should not be released when w3 becomes visible.
364 w3->Hide();
365 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
366 ->SetCapture(w2.get());
367 EXPECT_EQ(w2.get(),
368 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
369 ->GetGlobalCaptureWindow());
370 w3->Show();
371 EXPECT_EQ(w2.get(),
372 aura::client::GetCaptureClient(Shell::GetPrimaryRootWindow())
373 ->GetGlobalCaptureWindow());
374}
375
sadrul@chromium.org08ec21702012-07-11 00:49:44376class TouchTrackerWindowDelegate : public aura::test::TestWindowDelegate {
377 public:
tdresser@chromium.orgcb761f782013-10-21 19:19:42378 TouchTrackerWindowDelegate()
jamescookb8dcef522016-06-25 14:42:55379 : received_touch_(false), last_event_type_(ui::ET_UNKNOWN) {}
Peter Boströmec31a042021-09-16 23:37:34380
381 TouchTrackerWindowDelegate(const TouchTrackerWindowDelegate&) = delete;
382 TouchTrackerWindowDelegate& operator=(const TouchTrackerWindowDelegate&) =
383 delete;
384
Chris Watkinsc24daf62017-11-28 03:43:09385 ~TouchTrackerWindowDelegate() override = default;
sadrul@chromium.org08ec21702012-07-11 00:49:44386
387 void reset() {
388 received_touch_ = false;
tdresser@chromium.orgcb761f782013-10-21 19:19:42389 last_event_type_ = ui::ET_UNKNOWN;
sadrul@chromium.org08ec21702012-07-11 00:49:44390 }
391
392 bool received_touch() const { return received_touch_; }
tdresser@chromium.orgcb761f782013-10-21 19:19:42393 ui::EventType last_event_type() const { return last_event_type_; }
sadrul@chromium.org08ec21702012-07-11 00:49:44394
395 private:
396 // Overridden from aura::test::TestWindowDelegate.
dcheng28401c22014-10-28 01:26:19397 void OnTouchEvent(ui::TouchEvent* event) override {
sadrul@chromium.org08ec21702012-07-11 00:49:44398 received_touch_ = true;
tdresser@chromium.orgcb761f782013-10-21 19:19:42399 last_event_type_ = event->type();
sadrul@chromium.org6f34b4832012-12-14 16:18:08400 aura::test::TestWindowDelegate::OnTouchEvent(event);
sadrul@chromium.org08ec21702012-07-11 00:49:44401 }
402
403 bool received_touch_;
tdresser@chromium.orgcb761f782013-10-21 19:19:42404 ui::EventType last_event_type_;
sadrul@chromium.org08ec21702012-07-11 00:49:44405};
406
Weidong Guoa061f172018-11-14 03:01:15407// Modality should prevent events from being passed to transient window tree
408// rooted to the top level window.
sadrul@chromium.org08ec21702012-07-11 00:49:44409TEST_F(WindowModalityControllerTest, TouchEvent) {
410 TouchTrackerWindowDelegate d1;
dchenga94547472016-04-08 08:41:11411 std::unique_ptr<aura::Window> w1(
412 CreateTestWindowInShellWithDelegate(&d1, -1, gfx::Rect(0, 0, 100, 100)));
sadrul@chromium.org08ec21702012-07-11 00:49:44413 TouchTrackerWindowDelegate d11;
dchenga94547472016-04-08 08:41:11414 std::unique_ptr<aura::Window> w11(CreateTestWindowInShellWithDelegate(
Weidong Guoa061f172018-11-14 03:01:15415 &d11, -11, gfx::Rect(20, 20, 20, 20)));
416 TouchTrackerWindowDelegate d12;
417 std::unique_ptr<aura::Window> w12(CreateTestWindowInShellWithDelegate(
418 &d12, -12, gfx::Rect(40, 20, 20, 20)));
419 TouchTrackerWindowDelegate d2;
420 std::unique_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
421 &d2, -2, gfx::Rect(100, 0, 100, 100)));
422
423 // Make |w11| and |w12| non-resizable to avoid touch events inside its
424 // transient parent |w1| from going to them because of
425 // EasyResizeWindowTargeter.
Valery Arkhangorodsky7c9efb22017-07-13 20:08:06426 w11->SetProperty(aura::client::kResizeBehaviorKey,
Scott Violet97bdfa332019-05-23 22:42:50427 aura::client::kResizeBehaviorCanMaximize |
428 aura::client::kResizeBehaviorCanMinimize);
Weidong Guoa061f172018-11-14 03:01:15429 w12->SetProperty(aura::client::kResizeBehaviorKey,
Scott Violet97bdfa332019-05-23 22:42:50430 aura::client::kResizeBehaviorCanMaximize |
431 aura::client::kResizeBehaviorCanMinimize);
tapted@chromium.org73c9fd02014-07-28 01:48:52432 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
433 gfx::Point(10, 10));
sadrul@chromium.org08ec21702012-07-11 00:49:44434
ben@chromium.orge319c7e2014-03-14 19:56:14435 ::wm::AddTransientChild(w1.get(), w11.get());
Weidong Guoa061f172018-11-14 03:01:15436 ::wm::AddTransientChild(w1.get(), w12.get());
sadrul@chromium.org08ec21702012-07-11 00:49:44437 d1.reset();
438 d11.reset();
Weidong Guoa061f172018-11-14 03:01:15439 d12.reset();
440 d2.reset();
sadrul@chromium.org08ec21702012-07-11 00:49:44441
442 {
Weidong Guoa061f172018-11-14 03:01:15443 // Adding a modal window while a touch is down in top level transient window
444 // should fire a touch cancel.
tdresser@chromium.orgcb761f782013-10-21 19:19:42445 generator.PressTouch();
Weidong Guoa061f172018-11-14 03:01:15446 generator.MoveTouch(gfx::Point(10, 15));
447 EXPECT_TRUE(d1.received_touch());
448 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
tdresser@chromium.orgcb761f782013-10-21 19:19:42449 d1.reset();
450 d11.reset();
Weidong Guoa061f172018-11-14 03:01:15451 d12.reset();
452 d2.reset();
tdresser@chromium.orgcb761f782013-10-21 19:19:42453
454 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
455 EXPECT_TRUE(d1.received_touch());
456 EXPECT_EQ(ui::ET_TOUCH_CANCELLED, d1.last_event_type());
sadrul@chromium.org08ec21702012-07-11 00:49:44457 EXPECT_FALSE(d11.received_touch());
Weidong Guoa061f172018-11-14 03:01:15458 EXPECT_FALSE(d12.received_touch());
459 EXPECT_FALSE(d2.received_touch());
460 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
461 }
462
463 {
464 // Adding a modal window while a touch is down in window tree rooted to top
465 // level transient window should fire a touch cancel.
466 generator.MoveTouch(gfx::Point(50, 30));
467 generator.PressTouch();
468 generator.MoveTouch(gfx::Point(50, 35));
469 EXPECT_TRUE(d12.received_touch());
470 EXPECT_TRUE(wm::IsActiveWindow(w12.get()));
471 d1.reset();
472 d11.reset();
473 d12.reset();
474 d2.reset();
475
476 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
477 EXPECT_FALSE(d1.received_touch());
478 EXPECT_FALSE(d11.received_touch());
479 EXPECT_TRUE(d12.received_touch());
480 EXPECT_EQ(ui::ET_TOUCH_CANCELLED, d12.last_event_type());
481 EXPECT_FALSE(d2.received_touch());
482 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
483 }
484
485 {
486 // Adding a modal window while a touch is down in other transient window
487 // tree should not fire a touch cancel.
488 wm::ActivateWindow(w2.get());
489 generator.MoveTouch(gfx::Point(110, 10));
490 generator.PressTouch();
491 generator.MoveTouch(gfx::Point(110, 15));
492 EXPECT_TRUE(d2.received_touch());
493 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
494 d1.reset();
495 d11.reset();
496 d12.reset();
497 d2.reset();
498
499 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
500 EXPECT_FALSE(d1.received_touch());
501 EXPECT_FALSE(d11.received_touch());
502 EXPECT_FALSE(d12.received_touch());
503 EXPECT_FALSE(d2.received_touch());
504 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
505 }
506
507 {
508 // Adding a child type modal window while a touch is down in other transient
509 // window tree should not fire a touch cancel. (See
510 // https://crbug.com/900321)
511 wm::ActivateWindow(w2.get());
512 generator.MoveTouch(gfx::Point(110, 10));
513 generator.PressTouch();
514 generator.MoveTouch(gfx::Point(110, 15));
515 EXPECT_TRUE(d2.received_touch());
516 EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
517 d1.reset();
518 d11.reset();
519 d12.reset();
520 d2.reset();
521
522 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_CHILD);
523 EXPECT_FALSE(d1.received_touch());
524 EXPECT_FALSE(d11.received_touch());
525 EXPECT_FALSE(d12.received_touch());
526 EXPECT_FALSE(d2.received_touch());
527 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
sadrul@chromium.org08ec21702012-07-11 00:49:44528 }
529}
stevenjb@chromium.org0d9334b2012-03-14 04:52:28530
rouslan@chromium.org31d82f42012-11-28 16:48:21531// Child-modal test.
532// Creates:
Mike Wassermanff7c7f22018-07-16 19:07:33533// - A |top_level| window that hosts a |modal_parent| window within itself. The
534// |top_level| and |modal_parent| windows are not the same window. The
rouslan@chromium.org31d82f42012-11-28 16:48:21535// |modal_parent| window is not activatable, because it's contained within the
Mike Wassermanff7c7f22018-07-16 19:07:33536// |top_level| window.
537// - A |modal_child| window with parent window |top_level|, but is modal to
rouslan@chromium.org31d82f42012-11-28 16:48:21538// |modal_parent| window.
539// Validates:
Mike Wassermanff7c7f22018-07-16 19:07:33540// - Clicking on the |modal_parent| should activate the |modal_child| window.
541// - Clicking on the |top_level| window outside of the |modal_parent| bounds
542// should activate the |top_level| window.
543// - Clicking on the |modal_child| while |top_level| is active should activate
544// the |modal_child| window.
rouslan@chromium.org31d82f42012-11-28 16:48:21545// - Focus should follow the active window.
546TEST_F(WindowModalityControllerTest, ChildModal) {
Peter Kasting97defc92020-03-05 18:49:02547 TestChildModalParent* delegate = TestChildModalParent::Show(GetContext());
Mike Wassermanff7c7f22018-07-16 19:07:33548 aura::Window* top_level = delegate->GetWidget()->GetNativeView();
549 EXPECT_TRUE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21550
551 aura::Window* modal_parent = delegate->GetModalParent();
Mike Wasserman16f95212018-07-04 00:55:50552 EXPECT_NE(nullptr, modal_parent);
Mike Wassermanff7c7f22018-07-16 19:07:33553 EXPECT_NE(top_level, modal_parent);
rouslan@chromium.org31d82f42012-11-28 16:48:21554 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
555
Mike Wassermanff7c7f22018-07-16 19:07:33556 aura::Window* modal_child = delegate->ShowModalChild();
557 EXPECT_NE(nullptr, modal_child);
558 EXPECT_TRUE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21559 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33560 EXPECT_FALSE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21561
Mike Wassermanff7c7f22018-07-16 19:07:33562 EXPECT_TRUE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21563 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33564 EXPECT_FALSE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21565
566 wm::ActivateWindow(modal_parent);
567
Mike Wassermanff7c7f22018-07-16 19:07:33568 EXPECT_TRUE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21569 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33570 EXPECT_FALSE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21571
Mike Wassermanff7c7f22018-07-16 19:07:33572 EXPECT_TRUE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21573 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33574 EXPECT_FALSE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21575
Mike Wassermanff7c7f22018-07-16 19:07:33576 wm::ActivateWindow(top_level);
rouslan@chromium.org31d82f42012-11-28 16:48:21577
Mike Wassermanff7c7f22018-07-16 19:07:33578 EXPECT_FALSE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21579 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33580 EXPECT_TRUE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21581
Mike Wassermanff7c7f22018-07-16 19:07:33582 EXPECT_FALSE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21583 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33584 EXPECT_TRUE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21585
Mike Wassermanff7c7f22018-07-16 19:07:33586 wm::ActivateWindow(modal_child);
rouslan@chromium.org31d82f42012-11-28 16:48:21587
Mike Wassermanff7c7f22018-07-16 19:07:33588 EXPECT_TRUE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21589 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33590 EXPECT_FALSE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21591
Mike Wassermanff7c7f22018-07-16 19:07:33592 EXPECT_TRUE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21593 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33594 EXPECT_FALSE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21595}
596
597// Same as |ChildModal| test, but using |EventGenerator| rather than bypassing
598// it by calling |ActivateWindow|.
599TEST_F(WindowModalityControllerTest, ChildModalEventGenerator) {
Peter Kasting97defc92020-03-05 18:49:02600 TestChildModalParent* delegate = TestChildModalParent::Show(GetContext());
Mike Wassermanff7c7f22018-07-16 19:07:33601 aura::Window* top_level = delegate->GetWidget()->GetNativeView();
602 EXPECT_TRUE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21603
604 aura::Window* modal_parent = delegate->GetModalParent();
Mike Wasserman16f95212018-07-04 00:55:50605 EXPECT_NE(nullptr, modal_parent);
Mike Wassermanff7c7f22018-07-16 19:07:33606 EXPECT_NE(top_level, modal_parent);
rouslan@chromium.org31d82f42012-11-28 16:48:21607 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
608
Mike Wassermanff7c7f22018-07-16 19:07:33609 aura::Window* modal_child = delegate->ShowModalChild();
610 EXPECT_NE(nullptr, modal_child);
611 EXPECT_TRUE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21612 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33613 EXPECT_FALSE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21614
Mike Wassermanff7c7f22018-07-16 19:07:33615 EXPECT_TRUE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21616 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33617 EXPECT_FALSE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21618
619 {
tapted@chromium.org73c9fd02014-07-28 01:48:52620 ui::test::EventGenerator generator(
rouslan@chromium.org31d82f42012-11-28 16:48:21621 Shell::GetPrimaryRootWindow(),
Mike Wassermanff7c7f22018-07-16 19:07:33622 top_level->bounds().origin() +
623 gfx::Vector2d(10, top_level->bounds().height() - 10));
rouslan@chromium.org31d82f42012-11-28 16:48:21624 generator.ClickLeftButton();
625 generator.ClickLeftButton();
626
Mike Wassermanff7c7f22018-07-16 19:07:33627 EXPECT_TRUE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21628 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33629 EXPECT_FALSE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21630
Mike Wassermanff7c7f22018-07-16 19:07:33631 EXPECT_TRUE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21632 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33633 EXPECT_FALSE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21634 }
635
636 {
tapted@chromium.org73c9fd02014-07-28 01:48:52637 ui::test::EventGenerator generator(
rouslan@chromium.org31d82f42012-11-28 16:48:21638 Shell::GetPrimaryRootWindow(),
Mike Wassermanff7c7f22018-07-16 19:07:33639 top_level->bounds().origin() + gfx::Vector2d(10, 10));
rouslan@chromium.org31d82f42012-11-28 16:48:21640 generator.ClickLeftButton();
641
Mike Wassermanff7c7f22018-07-16 19:07:33642 EXPECT_FALSE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21643 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33644 EXPECT_TRUE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21645
Mike Wassermanff7c7f22018-07-16 19:07:33646 EXPECT_FALSE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21647 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33648 EXPECT_TRUE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21649 }
650
651 {
tapted@chromium.org73c9fd02014-07-28 01:48:52652 ui::test::EventGenerator generator(
rouslan@chromium.org31d82f42012-11-28 16:48:21653 Shell::GetPrimaryRootWindow(),
Mike Wassermanff7c7f22018-07-16 19:07:33654 modal_child->bounds().origin() + gfx::Vector2d(10, 10));
rouslan@chromium.org31d82f42012-11-28 16:48:21655 generator.ClickLeftButton();
656
Mike Wassermanff7c7f22018-07-16 19:07:33657 EXPECT_TRUE(wm::IsActiveWindow(modal_child));
rouslan@chromium.org31d82f42012-11-28 16:48:21658 EXPECT_FALSE(wm::IsActiveWindow(modal_parent));
Mike Wassermanff7c7f22018-07-16 19:07:33659 EXPECT_FALSE(wm::IsActiveWindow(top_level));
rouslan@chromium.org31d82f42012-11-28 16:48:21660
Mike Wassermanff7c7f22018-07-16 19:07:33661 EXPECT_TRUE(modal_child->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21662 EXPECT_FALSE(modal_parent->HasFocus());
Mike Wassermanff7c7f22018-07-16 19:07:33663 EXPECT_FALSE(top_level->HasFocus());
rouslan@chromium.org31d82f42012-11-28 16:48:21664 }
665}
666
667// Window-modal test for the case when the originally clicked window is an
668// ancestor of the modal parent.
669TEST_F(WindowModalityControllerTest, WindowModalAncestor) {
670 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11671 std::unique_ptr<aura::Window> w1(
erg@chromium.org5ebe6102012-11-28 21:00:03672 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:11673 std::unique_ptr<aura::Window> w2(
rouslan@chromium.org31d82f42012-11-28 16:48:21674 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get()));
dchenga94547472016-04-08 08:41:11675 std::unique_ptr<aura::Window> w3(
rouslan@chromium.org31d82f42012-11-28 16:48:21676 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w2.get()));
dchenga94547472016-04-08 08:41:11677 std::unique_ptr<aura::Window> w4(
erg@chromium.org5ebe6102012-11-28 21:00:03678 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
rouslan@chromium.org31d82f42012-11-28 16:48:21679 w4->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
ben@chromium.orge319c7e2014-03-14 19:56:14680 ::wm::AddTransientChild(w1.get(), w4.get());
rouslan@chromium.org31d82f42012-11-28 16:48:21681
682 wm::ActivateWindow(w1.get());
683 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
684
685 wm::ActivateWindow(w2.get());
686 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
687
688 wm::ActivateWindow(w3.get());
689 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
690
691 wm::ActivateWindow(w4.get());
692 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
693}
694
695// Child-modal test for the case when the originally clicked window is an
696// ancestor of the modal parent.
697TEST_F(WindowModalityControllerTest, ChildModalAncestor) {
698 aura::test::TestWindowDelegate d;
dchenga94547472016-04-08 08:41:11699 std::unique_ptr<aura::Window> w1(
erg@chromium.org5ebe6102012-11-28 21:00:03700 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect()));
dchenga94547472016-04-08 08:41:11701 std::unique_ptr<aura::Window> w2(
rouslan@chromium.org31d82f42012-11-28 16:48:21702 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get()));
dchenga94547472016-04-08 08:41:11703 std::unique_ptr<aura::Window> w3(
rouslan@chromium.org31d82f42012-11-28 16:48:21704 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w2.get()));
dchenga94547472016-04-08 08:41:11705 std::unique_ptr<aura::Window> w4(
erg@chromium.org5ebe6102012-11-28 21:00:03706 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect()));
rouslan@chromium.org31d82f42012-11-28 16:48:21707 w4->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_CHILD);
ben@chromium.orge319c7e2014-03-14 19:56:14708 ::wm::SetModalParent(w4.get(), w2.get());
709 ::wm::AddTransientChild(w1.get(), w4.get());
rouslan@chromium.org31d82f42012-11-28 16:48:21710
711 wm::ActivateWindow(w1.get());
712 EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
713
714 wm::ActivateWindow(w2.get());
715 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
716
717 wm::ActivateWindow(w3.get());
718 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
719
720 wm::ActivateWindow(w4.get());
721 EXPECT_TRUE(wm::IsActiveWindow(w4.get()));
722}
723
dhollowa@chromium.org8cc94c12012-01-20 22:49:27724} // namespace ash