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.
5 #include "ash/wm/system_modal_container_layout_manager.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/session/session_state_delegate.h"
10 #include "ash/shell_window_ids.h"
11 #include "ash/test/ash_test_base.h"
12 #include "ash/wm/window_util.h"
13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
15 #include "base/run_loop.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/compositor/layer.h"
19 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
20 #include "ui/compositor/test/layer_animator_test_controller.h"
21 #include "ui/events/test/event_generator.h"
22 #include "ui/gfx/screen.h"
23 #include "ui/keyboard/keyboard_controller.h"
24 #include "ui/keyboard/keyboard_controller_proxy.h"
25 #include "ui/keyboard/keyboard_switches.h"
26 #include "ui/keyboard/keyboard_util.h"
27 #include "ui/views/test/capture_tracking_view.h"
28 #include "ui/views/widget/widget.h"
29 #include "ui/views/widget/widget_delegate.h"
30 #include "ui/wm/core/window_util.h"
37 aura::Window
* GetModalContainer() {
38 return Shell::GetPrimaryRootWindowController()->GetContainer(
39 ash::kShellWindowId_SystemModalContainer
);
42 bool AllRootWindowsHaveModalBackgroundsForContainer(int container_id
) {
43 std::vector
<aura::Window
*> containers
=
44 Shell::GetContainersFromAllRootWindows(container_id
, NULL
);
45 bool has_modal_screen
= !containers
.empty();
46 for (std::vector
<aura::Window
*>::iterator iter
= containers
.begin();
47 iter
!= containers
.end(); ++iter
) {
48 has_modal_screen
&= static_cast<SystemModalContainerLayoutManager
*>(
49 (*iter
)->layout_manager())->has_modal_background();
51 return has_modal_screen
;
54 bool AllRootWindowsHaveLockedModalBackgrounds() {
55 return AllRootWindowsHaveModalBackgroundsForContainer(
56 kShellWindowId_LockSystemModalContainer
);
59 bool AllRootWindowsHaveModalBackgrounds() {
60 return AllRootWindowsHaveModalBackgroundsForContainer(
61 kShellWindowId_SystemModalContainer
);
64 class TestWindow
: public views::WidgetDelegateView
{
66 explicit TestWindow(bool modal
) : modal_(modal
) {}
67 ~TestWindow() override
{}
69 // The window needs be closed from widget in order for
70 // aura::client::kModalKey property to be reset.
71 static void CloseTestWindow(aura::Window
* window
) {
72 views::Widget::GetWidgetForNativeWindow(window
)->Close();
75 // Overridden from views::View:
76 gfx::Size
GetPreferredSize() const override
{ return gfx::Size(50, 50); }
78 // Overridden from views::WidgetDelegate:
79 views::View
* GetContentsView() override
{ return this; }
80 ui::ModalType
GetModalType() const override
{
81 return modal_
? ui::MODAL_TYPE_SYSTEM
: ui::MODAL_TYPE_NONE
;
87 DISALLOW_COPY_AND_ASSIGN(TestWindow
);
90 class EventTestWindow
: public TestWindow
{
92 explicit EventTestWindow(bool modal
) : TestWindow(modal
),
94 ~EventTestWindow() override
{}
96 aura::Window
* OpenTestWindowWithContext(aura::Window
* context
) {
97 views::Widget
* widget
=
98 views::Widget::CreateWindowWithContext(this, context
);
100 return widget
->GetNativeView();
103 aura::Window
* OpenTestWindowWithParent(aura::Window
* parent
) {
105 views::Widget
* widget
=
106 views::Widget::CreateWindowWithParent(this, parent
);
108 return widget
->GetNativeView();
111 // Overridden from views::View:
112 bool OnMousePressed(const ui::MouseEvent
& event
) override
{
117 int mouse_presses() const { return mouse_presses_
; }
121 DISALLOW_COPY_AND_ASSIGN(EventTestWindow
);
124 class TransientWindowObserver
: public aura::WindowObserver
{
126 TransientWindowObserver() : destroyed_(false) {}
127 ~TransientWindowObserver() override
{}
129 bool destroyed() const { return destroyed_
; }
131 // Overridden from aura::WindowObserver:
132 void OnWindowDestroyed(aura::Window
* window
) override
{ destroyed_
= true; }
137 DISALLOW_COPY_AND_ASSIGN(TransientWindowObserver
);
142 class SystemModalContainerLayoutManagerTest
: public AshTestBase
{
144 void SetUp() override
{
145 // Allow a virtual keyboard (and initialize it per default).
146 base::CommandLine::ForCurrentProcess()->AppendSwitch(
147 keyboard::switches::kEnableVirtualKeyboard
);
148 AshTestBase::SetUp();
149 Shell::GetPrimaryRootWindowController()->ActivateKeyboard(
150 keyboard::KeyboardController::GetInstance());
153 void TearDown() override
{
154 Shell::GetPrimaryRootWindowController()->DeactivateKeyboard(
155 keyboard::KeyboardController::GetInstance());
156 AshTestBase::TearDown();
159 aura::Window
* OpenToplevelTestWindow(bool modal
) {
160 views::Widget
* widget
= views::Widget::CreateWindowWithContext(
161 new TestWindow(modal
), CurrentContext());
163 return widget
->GetNativeView();
166 aura::Window
* OpenTestWindowWithParent(aura::Window
* parent
, bool modal
) {
167 views::Widget
* widget
=
168 views::Widget::CreateWindowWithParent(new TestWindow(modal
), parent
);
170 return widget
->GetNativeView();
173 // Show or hide the keyboard.
174 void ShowKeyboard(bool show
) {
175 keyboard::KeyboardController
* keyboard
=
176 keyboard::KeyboardController::GetInstance();
177 ASSERT_TRUE(keyboard
);
178 if (show
== keyboard
->keyboard_visible())
182 keyboard
->ShowKeyboard(true);
183 if (keyboard
->proxy()->GetKeyboardWindow()->bounds().height() == 0) {
184 keyboard
->proxy()->GetKeyboardWindow()->SetBounds(
185 keyboard::KeyboardBoundsFromWindowBounds(
186 keyboard
->GetContainerWindow()->bounds(), 100));
189 keyboard
->HideKeyboard(keyboard::KeyboardController::HIDE_REASON_MANUAL
);
192 DCHECK_EQ(show
, keyboard
->keyboard_visible());
197 TEST_F(SystemModalContainerLayoutManagerTest
, NonModalTransient
) {
198 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
199 aura::Window
* transient
= OpenTestWindowWithParent(parent
.get(), false);
200 TransientWindowObserver destruction_observer
;
201 transient
->AddObserver(&destruction_observer
);
203 EXPECT_EQ(parent
.get(), ::wm::GetTransientParent(transient
));
204 EXPECT_EQ(parent
->parent(), transient
->parent());
206 // The transient should be destroyed with its parent.
208 EXPECT_TRUE(destruction_observer
.destroyed());
211 TEST_F(SystemModalContainerLayoutManagerTest
, ModalTransient
) {
212 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
213 // parent should be active.
214 EXPECT_TRUE(wm::IsActiveWindow(parent
.get()));
215 aura::Window
* t1
= OpenTestWindowWithParent(parent
.get(), true);
217 TransientWindowObserver do1
;
218 t1
->AddObserver(&do1
);
220 EXPECT_EQ(parent
.get(), ::wm::GetTransientParent(t1
));
221 EXPECT_EQ(GetModalContainer(), t1
->parent());
223 // t1 should now be active.
224 EXPECT_TRUE(wm::IsActiveWindow(t1
));
226 // Attempting to click the parent should result in no activation change.
227 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(), parent
.get());
228 e1
.ClickLeftButton();
229 EXPECT_TRUE(wm::IsActiveWindow(t1
));
231 // Now open another modal transient parented to the original modal transient.
232 aura::Window
* t2
= OpenTestWindowWithParent(t1
, true);
233 TransientWindowObserver do2
;
234 t2
->AddObserver(&do2
);
236 EXPECT_TRUE(wm::IsActiveWindow(t2
));
238 EXPECT_EQ(t1
, ::wm::GetTransientParent(t2
));
239 EXPECT_EQ(GetModalContainer(), t2
->parent());
241 // t2 should still be active, even after clicking on t1.
242 ui::test::EventGenerator
e2(Shell::GetPrimaryRootWindow(), t1
);
243 e2
.ClickLeftButton();
244 EXPECT_TRUE(wm::IsActiveWindow(t2
));
246 // Both transients should be destroyed with parent.
248 EXPECT_TRUE(do1
.destroyed());
249 EXPECT_TRUE(do2
.destroyed());
252 TEST_F(SystemModalContainerLayoutManagerTest
, ModalNonTransient
) {
253 scoped_ptr
<aura::Window
> t1(OpenToplevelTestWindow(true));
254 // parent should be active.
255 EXPECT_TRUE(wm::IsActiveWindow(t1
.get()));
256 TransientWindowObserver do1
;
257 t1
->AddObserver(&do1
);
259 EXPECT_EQ(NULL
, ::wm::GetTransientParent(t1
.get()));
260 EXPECT_EQ(GetModalContainer(), t1
->parent());
262 // t1 should now be active.
263 EXPECT_TRUE(wm::IsActiveWindow(t1
.get()));
265 // Attempting to click the parent should result in no activation change.
266 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(),
267 Shell::GetPrimaryRootWindow());
268 e1
.ClickLeftButton();
269 EXPECT_TRUE(wm::IsActiveWindow(t1
.get()));
271 // Now open another modal transient parented to the original modal transient.
272 aura::Window
* t2
= OpenTestWindowWithParent(t1
.get(), true);
273 TransientWindowObserver do2
;
274 t2
->AddObserver(&do2
);
276 EXPECT_TRUE(wm::IsActiveWindow(t2
));
278 EXPECT_EQ(t1
, ::wm::GetTransientParent(t2
));
279 EXPECT_EQ(GetModalContainer(), t2
->parent());
281 // t2 should still be active, even after clicking on t1.
282 ui::test::EventGenerator
e2(Shell::GetPrimaryRootWindow(), t1
.get());
283 e2
.ClickLeftButton();
284 EXPECT_TRUE(wm::IsActiveWindow(t2
));
286 // Both transients should be destroyed with parent.
288 EXPECT_TRUE(do1
.destroyed());
289 EXPECT_TRUE(do2
.destroyed());
292 // Tests that we can activate an unrelated window after a modal window is closed
294 TEST_F(SystemModalContainerLayoutManagerTest
, CanActivateAfterEndModalSession
) {
295 scoped_ptr
<aura::Window
> unrelated(OpenToplevelTestWindow(false));
296 unrelated
->SetBounds(gfx::Rect(100, 100, 50, 50));
297 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
298 // parent should be active.
299 EXPECT_TRUE(wm::IsActiveWindow(parent
.get()));
301 scoped_ptr
<aura::Window
> transient(
302 OpenTestWindowWithParent(parent
.get(), true));
303 // t1 should now be active.
304 EXPECT_TRUE(wm::IsActiveWindow(transient
.get()));
306 // Attempting to click the parent should result in no activation change.
307 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(), parent
.get());
308 e1
.ClickLeftButton();
309 EXPECT_TRUE(wm::IsActiveWindow(transient
.get()));
311 // Now close the transient.
313 TestWindow::CloseTestWindow(transient
.release());
315 base::RunLoop().RunUntilIdle();
317 // parent should now be active again.
318 EXPECT_TRUE(wm::IsActiveWindow(parent
.get()));
320 // Attempting to click unrelated should activate it.
321 ui::test::EventGenerator
e2(Shell::GetPrimaryRootWindow(), unrelated
.get());
322 e2
.ClickLeftButton();
323 EXPECT_TRUE(wm::IsActiveWindow(unrelated
.get()));
326 TEST_F(SystemModalContainerLayoutManagerTest
, EventFocusContainers
) {
327 // Create a normal window and attempt to receive a click event.
328 EventTestWindow
* main_delegate
= new EventTestWindow(false);
329 scoped_ptr
<aura::Window
> main(
330 main_delegate
->OpenTestWindowWithContext(CurrentContext()));
331 EXPECT_TRUE(wm::IsActiveWindow(main
.get()));
332 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(), main
.get());
333 e1
.ClickLeftButton();
334 EXPECT_EQ(1, main_delegate
->mouse_presses());
336 // Create a modal window for the main window and verify that the main window
337 // no longer receives mouse events.
338 EventTestWindow
* transient_delegate
= new EventTestWindow(true);
339 aura::Window
* transient
=
340 transient_delegate
->OpenTestWindowWithParent(main
.get());
341 EXPECT_TRUE(wm::IsActiveWindow(transient
));
342 e1
.ClickLeftButton();
343 EXPECT_EQ(1, transient_delegate
->mouse_presses());
345 for (int block_reason
= FIRST_BLOCK_REASON
;
346 block_reason
< NUMBER_OF_BLOCK_REASONS
;
348 // Create a window in the lock screen container and ensure that it receives
349 // the mouse event instead of the modal window (crbug.com/110920).
350 BlockUserSession(static_cast<UserSessionBlockReason
>(block_reason
));
351 EventTestWindow
* lock_delegate
= new EventTestWindow(false);
352 scoped_ptr
<aura::Window
> lock(lock_delegate
->OpenTestWindowWithParent(
353 Shell::GetPrimaryRootWindowController()->GetContainer(
354 ash::kShellWindowId_LockScreenContainer
)));
355 EXPECT_TRUE(wm::IsActiveWindow(lock
.get()));
356 e1
.ClickLeftButton();
357 EXPECT_EQ(1, lock_delegate
->mouse_presses());
359 // Make sure that a modal container created by the lock screen can still
360 // receive mouse events.
361 EventTestWindow
* lock_modal_delegate
= new EventTestWindow(true);
362 aura::Window
* lock_modal
=
363 lock_modal_delegate
->OpenTestWindowWithParent(lock
.get());
364 EXPECT_TRUE(wm::IsActiveWindow(lock_modal
));
365 e1
.ClickLeftButton();
366 // Verify that none of the other containers received any more mouse presses.
367 EXPECT_EQ(1, lock_modal_delegate
->mouse_presses());
368 EXPECT_EQ(1, lock_delegate
->mouse_presses());
369 EXPECT_EQ(1, main_delegate
->mouse_presses());
370 EXPECT_EQ(1, transient_delegate
->mouse_presses());
371 UnblockUserSession();
375 // Makes sure we don't crash if a modal window is shown while the parent window
377 TEST_F(SystemModalContainerLayoutManagerTest
, ShowModalWhileHidden
) {
378 // Hide the lock screen.
379 Shell::GetPrimaryRootWindowController()
380 ->GetContainer(kShellWindowId_SystemModalContainer
)
384 // Create a modal window.
385 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
386 scoped_ptr
<aura::Window
> modal_window(
387 OpenTestWindowWithParent(parent
.get(), true));
389 modal_window
->Show();
392 // Verifies we generate a capture lost when showing a modal window.
393 TEST_F(SystemModalContainerLayoutManagerTest
, ChangeCapture
) {
394 views::Widget
* widget
= views::Widget::CreateWindowWithContext(
395 new TestWindow(false), CurrentContext());
396 scoped_ptr
<aura::Window
> widget_window(widget
->GetNativeView());
397 views::test::CaptureTrackingView
* view
= new views::test::CaptureTrackingView
;
398 widget
->GetContentsView()->AddChildView(view
);
399 view
->SetBoundsRect(widget
->GetContentsView()->bounds());
402 gfx::Point
center(view
->width() / 2, view
->height() / 2);
403 views::View::ConvertPointToScreen(view
, ¢er
);
404 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(), center
);
405 generator
.PressLeftButton();
406 EXPECT_TRUE(view
->got_press());
407 scoped_ptr
<aura::Window
> modal_window(
408 OpenTestWindowWithParent(widget
->GetNativeView(), true));
409 modal_window
->Show();
410 EXPECT_TRUE(view
->got_capture_lost());
413 // Verifies that the window gets moved into the visible screen area upon screen
415 TEST_F(SystemModalContainerLayoutManagerTest
, KeepVisible
) {
416 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
417 scoped_ptr
<aura::Window
> main(OpenTestWindowWithParent(GetModalContainer(),
419 main
->SetBounds(gfx::Rect(924, 668, 100, 100));
420 // We set now the bounds of the root window to something new which will
421 // Then trigger the repos operation.
422 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
424 gfx::Rect bounds
= main
->bounds();
425 EXPECT_EQ(bounds
, gfx::Rect(700, 500, 100, 100));
428 // Verifies that centered windows will remain centered after the visible screen
430 TEST_F(SystemModalContainerLayoutManagerTest
, KeepCentered
) {
431 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
432 scoped_ptr
<aura::Window
> main(OpenTestWindowWithParent(GetModalContainer(),
434 // Center the window.
435 main
->SetBounds(gfx::Rect((800 - 512) / 2, (600 - 256) / 2, 512, 256));
437 // We set now the bounds of the root window to something new which will
438 // Then trigger the reposition operation.
439 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
441 // The window should still be centered.
442 gfx::Rect bounds
= main
->bounds();
443 EXPECT_EQ(bounds
.ToString(), gfx::Rect(256, 256, 512, 256).ToString());
446 TEST_F(SystemModalContainerLayoutManagerTest
, ShowNormalBackgroundOrLocked
) {
447 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
448 scoped_ptr
<aura::Window
> modal_window(
449 OpenTestWindowWithParent(parent
.get(), true));
451 modal_window
->Show();
453 // Normal system modal window. Shows normal system modal background and not
455 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
456 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
458 TestWindow::CloseTestWindow(modal_window
.release());
459 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
460 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
462 for (int block_reason
= FIRST_BLOCK_REASON
;
463 block_reason
< NUMBER_OF_BLOCK_REASONS
;
465 // Normal system modal window while blocked. Shows blocked system modal
467 BlockUserSession(static_cast<UserSessionBlockReason
>(block_reason
));
468 scoped_ptr
<aura::Window
> lock_parent(OpenTestWindowWithParent(
469 Shell::GetPrimaryRootWindowController()->GetContainer(
470 ash::kShellWindowId_LockScreenContainer
),
472 scoped_ptr
<aura::Window
> lock_modal_window(OpenTestWindowWithParent(
473 lock_parent
.get(), true));
475 lock_modal_window
->Show();
476 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
477 EXPECT_TRUE(AllRootWindowsHaveLockedModalBackgrounds());
478 TestWindow::CloseTestWindow(lock_modal_window
.release());
480 // Normal system modal window while blocked, but it belongs to the normal
481 // window. Shouldn't show blocked system modal background, but normal.
482 scoped_ptr
<aura::Window
> modal_window(
483 OpenTestWindowWithParent(parent
.get(), true));
484 modal_window
->Show();
485 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
486 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
487 TestWindow::CloseTestWindow(modal_window
.release());
488 UnblockUserSession();
489 // Here we should check the behavior of the locked system modal dialog when
490 // unlocked, but such case isn't handled very well right now.
491 // See crbug.com/157660
492 // TODO(mukai): add the test case when the bug is fixed.
496 TEST_F(SystemModalContainerLayoutManagerTest
, MultiDisplays
) {
497 if (!SupportsMultipleDisplays())
500 UpdateDisplay("500x500,500x500");
502 scoped_ptr
<aura::Window
> normal(OpenToplevelTestWindow(false));
503 normal
->SetBounds(gfx::Rect(100, 100, 50, 50));
505 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
506 EXPECT_EQ(2U, root_windows
.size());
507 aura::Window
* container1
= Shell::GetContainer(
508 root_windows
[0], ash::kShellWindowId_SystemModalContainer
);
509 aura::Window
* container2
= Shell::GetContainer(
510 root_windows
[1], ash::kShellWindowId_SystemModalContainer
);
512 scoped_ptr
<aura::Window
> modal1(
513 OpenTestWindowWithParent(container1
, true));
514 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
515 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
517 scoped_ptr
<aura::Window
> modal11(
518 OpenTestWindowWithParent(container1
, true));
519 EXPECT_TRUE(wm::IsActiveWindow(modal11
.get()));
521 scoped_ptr
<aura::Window
> modal2(
522 OpenTestWindowWithParent(container2
, true));
523 EXPECT_TRUE(wm::IsActiveWindow(modal2
.get()));
525 // Sanity check if they're on the correct containers.
526 EXPECT_EQ(container1
, modal1
->parent());
527 EXPECT_EQ(container1
, modal11
->parent());
528 EXPECT_EQ(container2
, modal2
->parent());
530 TestWindow::CloseTestWindow(modal2
.release());
531 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
532 EXPECT_TRUE(wm::IsActiveWindow(modal11
.get()));
534 TestWindow::CloseTestWindow(modal11
.release());
535 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
536 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
538 UpdateDisplay("500x500");
539 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
540 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
542 UpdateDisplay("500x500,600x600");
543 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
544 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
546 // No more modal screen.
548 TestWindow::CloseTestWindow(modal1
.release());
549 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
550 EXPECT_TRUE(wm::IsActiveWindow(normal
.get()));
553 // Test that with the visible keyboard, an existing system modal dialog gets
554 // positioned into the visible area.
555 TEST_F(SystemModalContainerLayoutManagerTest
,
556 SystemModalDialogGetPushedFromKeyboard
) {
557 const gfx::Rect
& container_bounds
= GetModalContainer()->bounds();
558 // Place the window at the bottom of the screen.
559 gfx::Size
modal_size(100, 100);
560 gfx::Point modal_origin
= gfx::Point(
561 (container_bounds
.right() - modal_size
.width()) / 2, // X centered
562 container_bounds
.bottom() - modal_size
.height()); // at bottom
563 gfx::Rect modal_bounds
= gfx::Rect(modal_origin
, modal_size
);
565 // Create a modal window.
566 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
567 scoped_ptr
<aura::Window
> modal_window(
568 OpenTestWindowWithParent(parent
.get(), true));
569 modal_window
->SetBounds(modal_bounds
);
571 modal_window
->Show();
573 EXPECT_EQ(modal_bounds
.ToString(), modal_window
->bounds().ToString());
575 // The keyboard gets shown and the dialog should get pushed.
577 EXPECT_NE(modal_bounds
.ToString(), modal_window
->bounds().ToString());
578 EXPECT_GT(modal_bounds
.y(), modal_window
->bounds().y());
579 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
580 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
582 // After the keyboard is gone, the window will remain where it was.
584 EXPECT_NE(modal_bounds
.ToString(), modal_window
->bounds().ToString());
585 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
586 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
589 // Test that windows will not get cropped through the visible virtual keyboard -
591 TEST_F(SystemModalContainerLayoutManagerTest
,
592 SystemModalDialogGetPushedButNotCroppedFromKeyboard
) {
593 const gfx::Rect
& container_bounds
= GetModalContainer()->bounds();
594 const gfx::Size screen_size
= Shell::GetPrimaryRootWindow()->bounds().size();
595 // Place the window at the bottom of the screen.
596 gfx::Size
modal_size(100, screen_size
.height() - 70);
597 gfx::Point modal_origin
= gfx::Point(
598 (container_bounds
.right() - modal_size
.width()) / 2, // X centered
599 container_bounds
.bottom() - modal_size
.height()); // at bottom
600 gfx::Rect modal_bounds
= gfx::Rect(modal_origin
, modal_size
);
602 // Create a modal window.
603 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
604 scoped_ptr
<aura::Window
> modal_window(
605 OpenTestWindowWithParent(parent
.get(), true));
606 modal_window
->SetBounds(modal_bounds
);
608 modal_window
->Show();
610 EXPECT_EQ(modal_bounds
.ToString(), modal_window
->bounds().ToString());
612 // The keyboard gets shown and the dialog should get pushed up, but not get
613 // cropped (and aligned to the top).
615 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
616 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
617 EXPECT_EQ(0, modal_window
->bounds().y());
622 // Test that windows will not get cropped through the visible virtual keyboard -
624 TEST_F(SystemModalContainerLayoutManagerTest
,
625 SystemModalDialogGetPushedButNotCroppedFromKeyboardIfNotCentered
) {
626 const gfx::Size screen_size
= Shell::GetPrimaryRootWindow()->bounds().size();
627 // Place the window at the bottom of the screen.
628 gfx::Size
modal_size(100, screen_size
.height() - 70);
629 gfx::Point modal_origin
= gfx::Point(10, 20);
630 gfx::Rect modal_bounds
= gfx::Rect(modal_origin
, modal_size
);
632 // Create a modal window.
633 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
634 scoped_ptr
<aura::Window
> modal_window(
635 OpenTestWindowWithParent(parent
.get(), true));
636 modal_window
->SetBounds(modal_bounds
);
638 modal_window
->Show();
640 EXPECT_EQ(modal_bounds
.ToString(), modal_window
->bounds().ToString());
642 // The keyboard gets shown and the dialog should get pushed up, but not get
643 // cropped (and aligned to the top).
645 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
646 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
647 EXPECT_EQ(0, modal_window
->bounds().y());