1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/views/corewm/window_modality_controller.h" 6 7 #include "ash/shell.h" 8 #include "ash/test/ash_test_base.h" 9 #include "ash/wm/window_util.h" 10 #include "ui/aura/client/aura_constants.h" 11 #include "ui/aura/root_window.h" 12 #include "ui/aura/test/event_generator.h" 13 #include "ui/aura/test/test_window_delegate.h" 14 #include "ui/aura/test/test_windows.h" 15 #include "ui/aura/window.h" 16 #include "ui/base/ui_base_types.h" 17 #include "ui/views/test/capture_tracking_view.h" 18 #include "ui/views/test/child_modal_window.h" 19 #include "ui/views/widget/widget.h" 20 21 namespace ash { 22 namespace internal { 23 24 typedef test::AshTestBase WindowModalityControllerTest; 25 26 namespace { 27 28 bool ValidateStacking(aura::Window* parent, int ids[], int count) { 29 for (int i = 0; i < count; ++i) { 30 if (parent->children().at(i)->id() != ids[i]) 31 return false; 32 } 33 return true; 34 } 35 36 } // namespace 37 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. 43 // - closing a window passes focus up the stack. 44 TEST_F(WindowModalityControllerTest, BasicActivation) { 45 aura::test::TestWindowDelegate d; 46 scoped_ptr<aura::Window> w1( 47 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect())); 48 scoped_ptr<aura::Window> w11( 49 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect())); 50 scoped_ptr<aura::Window> w12( 51 CreateTestWindowInShellWithDelegate(&d, -12, gfx::Rect())); 52 53 w1->AddTransientChild(w11.get()); 54 wm::ActivateWindow(w1.get()); 55 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 56 wm::ActivateWindow(w11.get()); 57 EXPECT_TRUE(wm::IsActiveWindow(w11.get())); 58 59 w12->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 60 w1->AddTransientChild(w12.get()); 61 wm::ActivateWindow(w12.get()); 62 EXPECT_TRUE(wm::IsActiveWindow(w12.get())); 63 64 wm::ActivateWindow(w11.get()); 65 EXPECT_TRUE(wm::IsActiveWindow(w11.get())); 66 67 int check1[] = { -1, -12, -11 }; 68 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, arraysize(check1))); 69 70 wm::ActivateWindow(w1.get()); 71 EXPECT_TRUE(wm::IsActiveWindow(w12.get())); 72 // Transient children are always stacked above their transient parent, which 73 // is why this order is not -11, -1, -12. 74 int check2[] = { -1, -11, -12 }; 75 EXPECT_TRUE(ValidateStacking(w1->parent(), check2, arraysize(check2))); 76 77 w12.reset(); 78 EXPECT_TRUE(wm::IsActiveWindow(w11.get())); 79 w11.reset(); 80 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 81 } 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. 88 // - closing a window passes focus up the stack. 89 TEST_F(WindowModalityControllerTest, NestedModals) { 90 aura::test::TestWindowDelegate d; 91 scoped_ptr<aura::Window> w1( 92 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect())); 93 scoped_ptr<aura::Window> w11( 94 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect())); 95 scoped_ptr<aura::Window> w111( 96 CreateTestWindowInShellWithDelegate(&d, -111, gfx::Rect())); 97 scoped_ptr<aura::Window> w2( 98 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect())); 99 100 w1->AddTransientChild(w11.get()); 101 w11->AddTransientChild(w111.get()); 102 103 wm::ActivateWindow(w1.get()); 104 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 105 wm::ActivateWindow(w2.get()); 106 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); 107 108 // Set up modality. 109 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 110 w111->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 111 112 wm::ActivateWindow(w1.get()); 113 EXPECT_TRUE(wm::IsActiveWindow(w111.get())); 114 int check1[] = { -2, -1, -11, -111 }; 115 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, arraysize(check1))); 116 117 wm::ActivateWindow(w11.get()); 118 EXPECT_TRUE(wm::IsActiveWindow(w111.get())); 119 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, arraysize(check1))); 120 121 wm::ActivateWindow(w111.get()); 122 EXPECT_TRUE(wm::IsActiveWindow(w111.get())); 123 EXPECT_TRUE(ValidateStacking(w1->parent(), check1, arraysize(check1))); 124 125 wm::ActivateWindow(w2.get()); 126 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); 127 int check2[] = { -1, -11, -111, -2 }; 128 EXPECT_TRUE(ValidateStacking(w1->parent(), check2, arraysize(check2))); 129 130 w2.reset(); 131 EXPECT_TRUE(wm::IsActiveWindow(w111.get())); 132 w111.reset(); 133 EXPECT_TRUE(wm::IsActiveWindow(w11.get())); 134 w11.reset(); 135 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 136 } 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. 142 TEST_F(WindowModalityControllerTest, NestedModalsOuterClosed) { 143 aura::test::TestWindowDelegate d; 144 scoped_ptr<aura::Window> w1( 145 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect())); 146 scoped_ptr<aura::Window> w11( 147 CreateTestWindowInShellWithDelegate(&d, -11, gfx::Rect())); 148 // |w111| will be owned and deleted by |w11|. 149 aura::Window* w111 = 150 CreateTestWindowInShellWithDelegate(&d, -111, gfx::Rect()); 151 scoped_ptr<aura::Window> w2( 152 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect())); 153 154 w1->AddTransientChild(w11.get()); 155 w11->AddTransientChild(w111); 156 157 wm::ActivateWindow(w1.get()); 158 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 159 wm::ActivateWindow(w2.get()); 160 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); 161 162 // Set up modality. 163 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 164 w111->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 165 166 wm::ActivateWindow(w1.get()); 167 EXPECT_TRUE(wm::IsActiveWindow(w111)); 168 169 w111->Hide(); 170 EXPECT_TRUE(wm::IsActiveWindow(w11.get())); 171 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 176 w11.reset(); 177 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 178 } 179 180 // Modality also prevents events from being passed to the transient parent. 181 TEST_F(WindowModalityControllerTest, Events) { 182 aura::test::TestWindowDelegate d; 183 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(&d, -1, 184 gfx::Rect(0, 0, 100, 100))); 185 scoped_ptr<aura::Window> w11(CreateTestWindowInShellWithDelegate(&d, -11, 186 gfx::Rect(20, 20, 50, 50))); 187 188 w1->AddTransientChild(w11.get()); 189 190 { 191 // Clicking a point within w1 should activate that window. 192 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 193 gfx::Point(10, 10)); 194 generator.ClickLeftButton(); 195 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 196 } 197 198 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 199 200 { 201 // Clicking a point within w1 should activate w11. 202 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 203 gfx::Point(10, 10)); 204 generator.ClickLeftButton(); 205 EXPECT_TRUE(wm::IsActiveWindow(w11.get())); 206 } 207 } 208 209 // Creates windows w1 and non activatiable child w11. Creates transient window 210 // w2 and adds it as a transeint child of w1. Ensures that w2 is parented to 211 // the parent of w1, and that GetModalTransient(w11) returns w2. 212 TEST_F(WindowModalityControllerTest, GetModalTransient) { 213 aura::test::TestWindowDelegate d; 214 scoped_ptr<aura::Window> w1( 215 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect())); 216 scoped_ptr<aura::Window> w11( 217 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get())); 218 scoped_ptr<aura::Window> w2( 219 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect())); 220 w2->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 221 222 aura::Window* wt; 223 wt = views::corewm::GetModalTransient(w1.get()); 224 ASSERT_EQ(static_cast<aura::Window*>(NULL), wt); 225 226 // Parent w2 to w1. It should get parented to the parent of w1. 227 w1->AddTransientChild(w2.get()); 228 ASSERT_EQ(2U, w1->parent()->children().size()); 229 EXPECT_EQ(-2, w1->parent()->children().at(1)->id()); 230 231 // Request the modal transient window for w1, it should be w2. 232 wt = views::corewm::GetModalTransient(w1.get()); 233 ASSERT_NE(static_cast<aura::Window*>(NULL), wt); 234 EXPECT_EQ(-2, wt->id()); 235 236 // Request the modal transient window for w11, it should also be w2. 237 wt = views::corewm::GetModalTransient(w11.get()); 238 ASSERT_NE(static_cast<aura::Window*>(NULL), wt); 239 EXPECT_EQ(-2, wt->id()); 240 } 241 242 // Verifies we generate a capture lost when showing a modal window. 243 TEST_F(WindowModalityControllerTest, ChangeCapture) { 244 views::Widget* widget = views::Widget::CreateWindowWithContext( 245 NULL, Shell::GetPrimaryRootWindow()); 246 scoped_ptr<aura::Window> widget_window(widget->GetNativeView()); 247 views::test::CaptureTrackingView* view = new views::test::CaptureTrackingView; 248 widget->client_view()->AddChildView(view); 249 widget->SetBounds(gfx::Rect(0, 0, 200, 200)); 250 view->SetBoundsRect(widget->client_view()->GetLocalBounds()); 251 widget->Show(); 252 253 gfx::Point center(view->width() / 2, view->height() / 2); 254 views::View::ConvertPointToScreen(view, ¢er); 255 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), center); 256 generator.PressLeftButton(); 257 EXPECT_TRUE(view->got_press()); 258 259 views::Widget* modal_widget = 260 views::Widget::CreateWindowWithParent(NULL, widget->GetNativeView()); 261 scoped_ptr<aura::Window> modal_window(modal_widget->GetNativeView()); 262 modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 263 views::test::CaptureTrackingView* modal_view = 264 new views::test::CaptureTrackingView; 265 modal_widget->client_view()->AddChildView(modal_view); 266 modal_widget->SetBounds(gfx::Rect(50, 50, 200, 200)); 267 modal_view->SetBoundsRect(modal_widget->client_view()->GetLocalBounds()); 268 modal_widget->Show(); 269 270 EXPECT_TRUE(view->got_capture_lost()); 271 generator.ReleaseLeftButton(); 272 273 view->reset(); 274 275 EXPECT_FALSE(modal_view->got_capture_lost()); 276 EXPECT_FALSE(modal_view->got_press()); 277 278 gfx::Point modal_center(modal_view->width() / 2, modal_view->height() / 2); 279 views::View::ConvertPointToScreen(modal_view, &modal_center); 280 generator.MoveMouseTo(modal_center, 1); 281 generator.PressLeftButton(); 282 EXPECT_TRUE(modal_view->got_press()); 283 EXPECT_FALSE(modal_view->got_capture_lost()); 284 EXPECT_FALSE(view->got_capture_lost()); 285 EXPECT_FALSE(view->got_press()); 286 } 287 288 class TouchTrackerWindowDelegate : public aura::test::TestWindowDelegate { 289 public: 290 TouchTrackerWindowDelegate() 291 : received_touch_(false), 292 last_event_type_(ui::ET_UNKNOWN) { 293 } 294 virtual ~TouchTrackerWindowDelegate() {} 295 296 void reset() { 297 received_touch_ = false; 298 last_event_type_ = ui::ET_UNKNOWN; 299 } 300 301 bool received_touch() const { return received_touch_; } 302 ui::EventType last_event_type() const { return last_event_type_; } 303 304 private: 305 // Overridden from aura::test::TestWindowDelegate. 306 virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { 307 received_touch_ = true; 308 last_event_type_ = event->type(); 309 aura::test::TestWindowDelegate::OnTouchEvent(event); 310 } 311 312 bool received_touch_; 313 ui::EventType last_event_type_; 314 315 DISALLOW_COPY_AND_ASSIGN(TouchTrackerWindowDelegate); 316 }; 317 318 // Modality should prevent events from being passed to the transient parent. 319 TEST_F(WindowModalityControllerTest, TouchEvent) { 320 TouchTrackerWindowDelegate d1; 321 scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(&d1, 322 -1, gfx::Rect(0, 0, 100, 100))); 323 TouchTrackerWindowDelegate d11; 324 scoped_ptr<aura::Window> w11(CreateTestWindowInShellWithDelegate(&d11, 325 -11, gfx::Rect(20, 20, 50, 50))); 326 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), 327 gfx::Point(10, 10)); 328 329 w1->AddTransientChild(w11.get()); 330 d1.reset(); 331 d11.reset(); 332 333 { 334 // Clicking a point within w1 should activate that window. 335 generator.PressMoveAndReleaseTouchTo(gfx::Point(10, 10)); 336 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 337 EXPECT_TRUE(d1.received_touch()); 338 EXPECT_FALSE(d11.received_touch()); 339 } 340 341 { 342 // Adding a modal window while a touch is down should fire a touch cancel. 343 generator.PressTouch(); 344 generator.MoveTouch(gfx::Point(10, 10)); 345 d1.reset(); 346 d11.reset(); 347 348 w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 349 EXPECT_TRUE(d1.received_touch()); 350 EXPECT_EQ(ui::ET_TOUCH_CANCELLED, d1.last_event_type()); 351 EXPECT_FALSE(d11.received_touch()); 352 } 353 } 354 355 // Child-modal test. 356 // Creates: 357 // - A |parent| window that hosts a |modal_parent| window within itself. The 358 // |parent| and |modal_parent| windows are not the same window. The 359 // |modal_parent| window is not activatable, because it's contained within the 360 // |parent| window. 361 // - A |child| window with parent window |parent|, but is modal to 362 // |modal_parent| window. 363 // Validates: 364 // - Clicking on the |modal_parent| should activate the |child| window. 365 // - Clicking on the |parent| window outside of the |modal_parent| bounds should 366 // activate the |parent| window. 367 // - Clicking on the |child| while |parent| is active should activate the 368 // |child| window. 369 // - Focus should follow the active window. 370 TEST_F(WindowModalityControllerTest, ChildModal) { 371 views::test::ChildModalParent* delegate = 372 new views::test::ChildModalParent(CurrentContext()); 373 views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds( 374 delegate, CurrentContext(), gfx::Rect(0, 0, 400, 400)); 375 widget->Show(); 376 377 aura::Window* parent = widget->GetNativeView(); 378 EXPECT_TRUE(wm::IsActiveWindow(parent)); 379 380 aura::Window* modal_parent = delegate->GetModalParent(); 381 EXPECT_NE(static_cast<aura::Window*>(NULL), modal_parent); 382 EXPECT_NE(parent, modal_parent); 383 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 384 385 delegate->ShowChild(); 386 aura::Window* child = delegate->GetChild(); 387 EXPECT_NE(static_cast<aura::Window*>(NULL), child); 388 389 EXPECT_TRUE(wm::IsActiveWindow(child)); 390 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 391 EXPECT_FALSE(wm::IsActiveWindow(parent)); 392 393 EXPECT_TRUE(child->HasFocus()); 394 EXPECT_FALSE(modal_parent->HasFocus()); 395 EXPECT_FALSE(parent->HasFocus()); 396 397 wm::ActivateWindow(modal_parent); 398 399 EXPECT_TRUE(wm::IsActiveWindow(child)); 400 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 401 EXPECT_FALSE(wm::IsActiveWindow(parent)); 402 403 EXPECT_TRUE(child->HasFocus()); 404 EXPECT_FALSE(modal_parent->HasFocus()); 405 EXPECT_FALSE(parent->HasFocus()); 406 407 wm::ActivateWindow(parent); 408 409 EXPECT_FALSE(wm::IsActiveWindow(child)); 410 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 411 EXPECT_TRUE(wm::IsActiveWindow(parent)); 412 413 EXPECT_FALSE(child->HasFocus()); 414 EXPECT_FALSE(modal_parent->HasFocus()); 415 EXPECT_TRUE(parent->HasFocus()); 416 417 wm::ActivateWindow(child); 418 419 EXPECT_TRUE(wm::IsActiveWindow(child)); 420 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 421 EXPECT_FALSE(wm::IsActiveWindow(parent)); 422 423 EXPECT_TRUE(child->HasFocus()); 424 EXPECT_FALSE(modal_parent->HasFocus()); 425 EXPECT_FALSE(parent->HasFocus()); 426 } 427 428 // Same as |ChildModal| test, but using |EventGenerator| rather than bypassing 429 // it by calling |ActivateWindow|. 430 TEST_F(WindowModalityControllerTest, ChildModalEventGenerator) { 431 views::test::ChildModalParent* delegate = 432 new views::test::ChildModalParent(CurrentContext()); 433 views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds( 434 delegate, CurrentContext(), gfx::Rect(0, 0, 400, 400)); 435 widget->Show(); 436 437 aura::Window* parent = widget->GetNativeView(); 438 EXPECT_TRUE(wm::IsActiveWindow(parent)); 439 440 aura::Window* modal_parent = delegate->GetModalParent(); 441 EXPECT_NE(static_cast<aura::Window*>(NULL), modal_parent); 442 EXPECT_NE(parent, modal_parent); 443 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 444 445 delegate->ShowChild(); 446 aura::Window* child = delegate->GetChild(); 447 EXPECT_NE(static_cast<aura::Window*>(NULL), child); 448 449 EXPECT_TRUE(wm::IsActiveWindow(child)); 450 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 451 EXPECT_FALSE(wm::IsActiveWindow(parent)); 452 453 EXPECT_TRUE(child->HasFocus()); 454 EXPECT_FALSE(modal_parent->HasFocus()); 455 EXPECT_FALSE(parent->HasFocus()); 456 457 { 458 aura::test::EventGenerator generator( 459 Shell::GetPrimaryRootWindow(), 460 parent->bounds().origin() + 461 gfx::Vector2d(10, parent->bounds().height() - 10)); 462 generator.ClickLeftButton(); 463 generator.ClickLeftButton(); 464 465 EXPECT_TRUE(wm::IsActiveWindow(child)); 466 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 467 EXPECT_FALSE(wm::IsActiveWindow(parent)); 468 469 EXPECT_TRUE(child->HasFocus()); 470 EXPECT_FALSE(modal_parent->HasFocus()); 471 EXPECT_FALSE(parent->HasFocus()); 472 } 473 474 { 475 aura::test::EventGenerator generator( 476 Shell::GetPrimaryRootWindow(), 477 parent->bounds().origin() + gfx::Vector2d(10, 10)); 478 generator.ClickLeftButton(); 479 480 EXPECT_FALSE(wm::IsActiveWindow(child)); 481 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 482 EXPECT_TRUE(wm::IsActiveWindow(parent)); 483 484 EXPECT_FALSE(child->HasFocus()); 485 EXPECT_FALSE(modal_parent->HasFocus()); 486 EXPECT_TRUE(parent->HasFocus()); 487 } 488 489 { 490 aura::test::EventGenerator generator( 491 Shell::GetPrimaryRootWindow(), 492 child->bounds().origin() + gfx::Vector2d(10, 10)); 493 generator.ClickLeftButton(); 494 495 EXPECT_TRUE(wm::IsActiveWindow(child)); 496 EXPECT_FALSE(wm::IsActiveWindow(modal_parent)); 497 EXPECT_FALSE(wm::IsActiveWindow(parent)); 498 499 EXPECT_TRUE(child->HasFocus()); 500 EXPECT_FALSE(modal_parent->HasFocus()); 501 EXPECT_FALSE(parent->HasFocus()); 502 } 503 } 504 505 // Window-modal test for the case when the originally clicked window is an 506 // ancestor of the modal parent. 507 TEST_F(WindowModalityControllerTest, WindowModalAncestor) { 508 aura::test::TestWindowDelegate d; 509 scoped_ptr<aura::Window> w1( 510 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect())); 511 scoped_ptr<aura::Window> w2( 512 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get())); 513 scoped_ptr<aura::Window> w3( 514 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w2.get())); 515 scoped_ptr<aura::Window> w4( 516 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect())); 517 w4->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); 518 w1->AddTransientChild(w4.get()); 519 520 wm::ActivateWindow(w1.get()); 521 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 522 523 wm::ActivateWindow(w2.get()); 524 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 525 526 wm::ActivateWindow(w3.get()); 527 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 528 529 wm::ActivateWindow(w4.get()); 530 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 531 } 532 533 // Child-modal test for the case when the originally clicked window is an 534 // ancestor of the modal parent. 535 TEST_F(WindowModalityControllerTest, ChildModalAncestor) { 536 aura::test::TestWindowDelegate d; 537 scoped_ptr<aura::Window> w1( 538 CreateTestWindowInShellWithDelegate(&d, -1, gfx::Rect())); 539 scoped_ptr<aura::Window> w2( 540 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w1.get())); 541 scoped_ptr<aura::Window> w3( 542 aura::test::CreateTestWindowWithDelegate(&d, -11, gfx::Rect(), w2.get())); 543 scoped_ptr<aura::Window> w4( 544 CreateTestWindowInShellWithDelegate(&d, -2, gfx::Rect())); 545 w4->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_CHILD); 546 views::corewm::SetModalParent(w4.get(), w2.get()); 547 w1->AddTransientChild(w4.get()); 548 549 wm::ActivateWindow(w1.get()); 550 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); 551 552 wm::ActivateWindow(w2.get()); 553 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 554 555 wm::ActivateWindow(w3.get()); 556 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 557 558 wm::ActivateWindow(w4.get()); 559 EXPECT_TRUE(wm::IsActiveWindow(w4.get())); 560 } 561 562 } // namespace internal 563 } // namespace ash 564