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 virtual ~TestWindow() {}
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 virtual gfx::Size
GetPreferredSize() const OVERRIDE
{
77 return gfx::Size(50, 50);
80 // Overridden from views::WidgetDelegate:
81 virtual views::View
* GetContentsView() OVERRIDE
{
84 virtual ui::ModalType
GetModalType() const OVERRIDE
{
85 return modal_
? ui::MODAL_TYPE_SYSTEM
: ui::MODAL_TYPE_NONE
;
91 DISALLOW_COPY_AND_ASSIGN(TestWindow
);
94 class EventTestWindow
: public TestWindow
{
96 explicit EventTestWindow(bool modal
) : TestWindow(modal
),
98 virtual ~EventTestWindow() {}
100 aura::Window
* OpenTestWindowWithContext(aura::Window
* context
) {
101 views::Widget
* widget
=
102 views::Widget::CreateWindowWithContext(this, context
);
104 return widget
->GetNativeView();
107 aura::Window
* OpenTestWindowWithParent(aura::Window
* parent
) {
109 views::Widget
* widget
=
110 views::Widget::CreateWindowWithParent(this, parent
);
112 return widget
->GetNativeView();
115 // Overridden from views::View:
116 virtual bool OnMousePressed(const ui::MouseEvent
& event
) OVERRIDE
{
121 int mouse_presses() const { return mouse_presses_
; }
125 DISALLOW_COPY_AND_ASSIGN(EventTestWindow
);
128 class TransientWindowObserver
: public aura::WindowObserver
{
130 TransientWindowObserver() : destroyed_(false) {}
131 virtual ~TransientWindowObserver() {}
133 bool destroyed() const { return destroyed_
; }
135 // Overridden from aura::WindowObserver:
136 virtual void OnWindowDestroyed(aura::Window
* window
) OVERRIDE
{
143 DISALLOW_COPY_AND_ASSIGN(TransientWindowObserver
);
148 class SystemModalContainerLayoutManagerTest
: public AshTestBase
{
150 virtual void SetUp() OVERRIDE
{
151 // Allow a virtual keyboard (and initialize it per default).
152 CommandLine::ForCurrentProcess()->AppendSwitch(
153 keyboard::switches::kEnableVirtualKeyboard
);
154 AshTestBase::SetUp();
155 Shell::GetPrimaryRootWindowController()->ActivateKeyboard(
156 keyboard::KeyboardController::GetInstance());
159 virtual void TearDown() OVERRIDE
{
160 Shell::GetPrimaryRootWindowController()->DeactivateKeyboard(
161 keyboard::KeyboardController::GetInstance());
162 AshTestBase::TearDown();
165 aura::Window
* OpenToplevelTestWindow(bool modal
) {
166 views::Widget
* widget
= views::Widget::CreateWindowWithContext(
167 new TestWindow(modal
), CurrentContext());
169 return widget
->GetNativeView();
172 aura::Window
* OpenTestWindowWithParent(aura::Window
* parent
, bool modal
) {
173 views::Widget
* widget
=
174 views::Widget::CreateWindowWithParent(new TestWindow(modal
), parent
);
176 return widget
->GetNativeView();
179 // Show or hide the keyboard.
180 void ShowKeyboard(bool show
) {
181 keyboard::KeyboardController
* keyboard
=
182 keyboard::KeyboardController::GetInstance();
183 ASSERT_TRUE(keyboard
);
184 if (show
== keyboard
->keyboard_visible())
188 keyboard
->ShowKeyboard(true);
189 if (keyboard
->proxy()->GetKeyboardWindow()->bounds().height() == 0) {
190 keyboard
->proxy()->GetKeyboardWindow()->SetBounds(
191 keyboard::KeyboardBoundsFromWindowBounds(
192 keyboard
->GetContainerWindow()->bounds(), 100));
195 keyboard
->HideKeyboard(keyboard::KeyboardController::HIDE_REASON_MANUAL
);
198 DCHECK_EQ(show
, keyboard
->keyboard_visible());
203 TEST_F(SystemModalContainerLayoutManagerTest
, NonModalTransient
) {
204 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
205 aura::Window
* transient
= OpenTestWindowWithParent(parent
.get(), false);
206 TransientWindowObserver destruction_observer
;
207 transient
->AddObserver(&destruction_observer
);
209 EXPECT_EQ(parent
.get(), ::wm::GetTransientParent(transient
));
210 EXPECT_EQ(parent
->parent(), transient
->parent());
212 // The transient should be destroyed with its parent.
214 EXPECT_TRUE(destruction_observer
.destroyed());
217 TEST_F(SystemModalContainerLayoutManagerTest
, ModalTransient
) {
218 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
219 // parent should be active.
220 EXPECT_TRUE(wm::IsActiveWindow(parent
.get()));
221 aura::Window
* t1
= OpenTestWindowWithParent(parent
.get(), true);
223 TransientWindowObserver do1
;
224 t1
->AddObserver(&do1
);
226 EXPECT_EQ(parent
.get(), ::wm::GetTransientParent(t1
));
227 EXPECT_EQ(GetModalContainer(), t1
->parent());
229 // t1 should now be active.
230 EXPECT_TRUE(wm::IsActiveWindow(t1
));
232 // Attempting to click the parent should result in no activation change.
233 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(), parent
.get());
234 e1
.ClickLeftButton();
235 EXPECT_TRUE(wm::IsActiveWindow(t1
));
237 // Now open another modal transient parented to the original modal transient.
238 aura::Window
* t2
= OpenTestWindowWithParent(t1
, true);
239 TransientWindowObserver do2
;
240 t2
->AddObserver(&do2
);
242 EXPECT_TRUE(wm::IsActiveWindow(t2
));
244 EXPECT_EQ(t1
, ::wm::GetTransientParent(t2
));
245 EXPECT_EQ(GetModalContainer(), t2
->parent());
247 // t2 should still be active, even after clicking on t1.
248 ui::test::EventGenerator
e2(Shell::GetPrimaryRootWindow(), t1
);
249 e2
.ClickLeftButton();
250 EXPECT_TRUE(wm::IsActiveWindow(t2
));
252 // Both transients should be destroyed with parent.
254 EXPECT_TRUE(do1
.destroyed());
255 EXPECT_TRUE(do2
.destroyed());
258 TEST_F(SystemModalContainerLayoutManagerTest
, ModalNonTransient
) {
259 scoped_ptr
<aura::Window
> t1(OpenToplevelTestWindow(true));
260 // parent should be active.
261 EXPECT_TRUE(wm::IsActiveWindow(t1
.get()));
262 TransientWindowObserver do1
;
263 t1
->AddObserver(&do1
);
265 EXPECT_EQ(NULL
, ::wm::GetTransientParent(t1
.get()));
266 EXPECT_EQ(GetModalContainer(), t1
->parent());
268 // t1 should now be active.
269 EXPECT_TRUE(wm::IsActiveWindow(t1
.get()));
271 // Attempting to click the parent should result in no activation change.
272 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(),
273 Shell::GetPrimaryRootWindow());
274 e1
.ClickLeftButton();
275 EXPECT_TRUE(wm::IsActiveWindow(t1
.get()));
277 // Now open another modal transient parented to the original modal transient.
278 aura::Window
* t2
= OpenTestWindowWithParent(t1
.get(), true);
279 TransientWindowObserver do2
;
280 t2
->AddObserver(&do2
);
282 EXPECT_TRUE(wm::IsActiveWindow(t2
));
284 EXPECT_EQ(t1
, ::wm::GetTransientParent(t2
));
285 EXPECT_EQ(GetModalContainer(), t2
->parent());
287 // t2 should still be active, even after clicking on t1.
288 ui::test::EventGenerator
e2(Shell::GetPrimaryRootWindow(), t1
.get());
289 e2
.ClickLeftButton();
290 EXPECT_TRUE(wm::IsActiveWindow(t2
));
292 // Both transients should be destroyed with parent.
294 EXPECT_TRUE(do1
.destroyed());
295 EXPECT_TRUE(do2
.destroyed());
298 // Tests that we can activate an unrelated window after a modal window is closed
300 TEST_F(SystemModalContainerLayoutManagerTest
, CanActivateAfterEndModalSession
) {
301 scoped_ptr
<aura::Window
> unrelated(OpenToplevelTestWindow(false));
302 unrelated
->SetBounds(gfx::Rect(100, 100, 50, 50));
303 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
304 // parent should be active.
305 EXPECT_TRUE(wm::IsActiveWindow(parent
.get()));
307 scoped_ptr
<aura::Window
> transient(
308 OpenTestWindowWithParent(parent
.get(), true));
309 // t1 should now be active.
310 EXPECT_TRUE(wm::IsActiveWindow(transient
.get()));
312 // Attempting to click the parent should result in no activation change.
313 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(), parent
.get());
314 e1
.ClickLeftButton();
315 EXPECT_TRUE(wm::IsActiveWindow(transient
.get()));
317 // Now close the transient.
319 TestWindow::CloseTestWindow(transient
.release());
321 base::RunLoop().RunUntilIdle();
323 // parent should now be active again.
324 EXPECT_TRUE(wm::IsActiveWindow(parent
.get()));
326 // Attempting to click unrelated should activate it.
327 ui::test::EventGenerator
e2(Shell::GetPrimaryRootWindow(), unrelated
.get());
328 e2
.ClickLeftButton();
329 EXPECT_TRUE(wm::IsActiveWindow(unrelated
.get()));
332 TEST_F(SystemModalContainerLayoutManagerTest
, EventFocusContainers
) {
333 // Create a normal window and attempt to receive a click event.
334 EventTestWindow
* main_delegate
= new EventTestWindow(false);
335 scoped_ptr
<aura::Window
> main(
336 main_delegate
->OpenTestWindowWithContext(CurrentContext()));
337 EXPECT_TRUE(wm::IsActiveWindow(main
.get()));
338 ui::test::EventGenerator
e1(Shell::GetPrimaryRootWindow(), main
.get());
339 e1
.ClickLeftButton();
340 EXPECT_EQ(1, main_delegate
->mouse_presses());
342 // Create a modal window for the main window and verify that the main window
343 // no longer receives mouse events.
344 EventTestWindow
* transient_delegate
= new EventTestWindow(true);
345 aura::Window
* transient
=
346 transient_delegate
->OpenTestWindowWithParent(main
.get());
347 EXPECT_TRUE(wm::IsActiveWindow(transient
));
348 e1
.ClickLeftButton();
349 EXPECT_EQ(1, transient_delegate
->mouse_presses());
351 for (int block_reason
= FIRST_BLOCK_REASON
;
352 block_reason
< NUMBER_OF_BLOCK_REASONS
;
354 // Create a window in the lock screen container and ensure that it receives
355 // the mouse event instead of the modal window (crbug.com/110920).
356 BlockUserSession(static_cast<UserSessionBlockReason
>(block_reason
));
357 EventTestWindow
* lock_delegate
= new EventTestWindow(false);
358 scoped_ptr
<aura::Window
> lock(lock_delegate
->OpenTestWindowWithParent(
359 Shell::GetPrimaryRootWindowController()->GetContainer(
360 ash::kShellWindowId_LockScreenContainer
)));
361 EXPECT_TRUE(wm::IsActiveWindow(lock
.get()));
362 e1
.ClickLeftButton();
363 EXPECT_EQ(1, lock_delegate
->mouse_presses());
365 // Make sure that a modal container created by the lock screen can still
366 // receive mouse events.
367 EventTestWindow
* lock_modal_delegate
= new EventTestWindow(true);
368 aura::Window
* lock_modal
=
369 lock_modal_delegate
->OpenTestWindowWithParent(lock
.get());
370 EXPECT_TRUE(wm::IsActiveWindow(lock_modal
));
371 e1
.ClickLeftButton();
372 // Verify that none of the other containers received any more mouse presses.
373 EXPECT_EQ(1, lock_modal_delegate
->mouse_presses());
374 EXPECT_EQ(1, lock_delegate
->mouse_presses());
375 EXPECT_EQ(1, main_delegate
->mouse_presses());
376 EXPECT_EQ(1, transient_delegate
->mouse_presses());
377 UnblockUserSession();
381 // Makes sure we don't crash if a modal window is shown while the parent window
383 TEST_F(SystemModalContainerLayoutManagerTest
, ShowModalWhileHidden
) {
384 // Hide the lock screen.
385 Shell::GetPrimaryRootWindowController()
386 ->GetContainer(kShellWindowId_SystemModalContainer
)
390 // Create a modal window.
391 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
392 scoped_ptr
<aura::Window
> modal_window(
393 OpenTestWindowWithParent(parent
.get(), true));
395 modal_window
->Show();
398 // Verifies we generate a capture lost when showing a modal window.
399 TEST_F(SystemModalContainerLayoutManagerTest
, ChangeCapture
) {
400 views::Widget
* widget
= views::Widget::CreateWindowWithContext(
401 new TestWindow(false), CurrentContext());
402 scoped_ptr
<aura::Window
> widget_window(widget
->GetNativeView());
403 views::test::CaptureTrackingView
* view
= new views::test::CaptureTrackingView
;
404 widget
->GetContentsView()->AddChildView(view
);
405 view
->SetBoundsRect(widget
->GetContentsView()->bounds());
408 gfx::Point
center(view
->width() / 2, view
->height() / 2);
409 views::View::ConvertPointToScreen(view
, ¢er
);
410 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(), center
);
411 generator
.PressLeftButton();
412 EXPECT_TRUE(view
->got_press());
413 scoped_ptr
<aura::Window
> modal_window(
414 OpenTestWindowWithParent(widget
->GetNativeView(), true));
415 modal_window
->Show();
416 EXPECT_TRUE(view
->got_capture_lost());
419 // Verifies that the window gets moved into the visible screen area upon screen
421 TEST_F(SystemModalContainerLayoutManagerTest
, KeepVisible
) {
422 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
423 scoped_ptr
<aura::Window
> main(OpenTestWindowWithParent(GetModalContainer(),
425 main
->SetBounds(gfx::Rect(924, 668, 100, 100));
426 // We set now the bounds of the root window to something new which will
427 // Then trigger the repos operation.
428 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
430 gfx::Rect bounds
= main
->bounds();
431 EXPECT_EQ(bounds
, gfx::Rect(700, 500, 100, 100));
434 // Verifies that centered windows will remain centered after the visible screen
436 TEST_F(SystemModalContainerLayoutManagerTest
, KeepCentered
) {
437 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
438 scoped_ptr
<aura::Window
> main(OpenTestWindowWithParent(GetModalContainer(),
440 // Center the window.
441 main
->SetBounds(gfx::Rect((800 - 512) / 2, (600 - 256) / 2, 512, 256));
443 // We set now the bounds of the root window to something new which will
444 // Then trigger the reposition operation.
445 GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
447 // The window should still be centered.
448 gfx::Rect bounds
= main
->bounds();
449 EXPECT_EQ(bounds
.ToString(), gfx::Rect(256, 256, 512, 256).ToString());
452 TEST_F(SystemModalContainerLayoutManagerTest
, ShowNormalBackgroundOrLocked
) {
453 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
454 scoped_ptr
<aura::Window
> modal_window(
455 OpenTestWindowWithParent(parent
.get(), true));
457 modal_window
->Show();
459 // Normal system modal window. Shows normal system modal background and not
461 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
462 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
464 TestWindow::CloseTestWindow(modal_window
.release());
465 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
466 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
468 for (int block_reason
= FIRST_BLOCK_REASON
;
469 block_reason
< NUMBER_OF_BLOCK_REASONS
;
471 // Normal system modal window while blocked. Shows blocked system modal
473 BlockUserSession(static_cast<UserSessionBlockReason
>(block_reason
));
474 scoped_ptr
<aura::Window
> lock_parent(OpenTestWindowWithParent(
475 Shell::GetPrimaryRootWindowController()->GetContainer(
476 ash::kShellWindowId_LockScreenContainer
),
478 scoped_ptr
<aura::Window
> lock_modal_window(OpenTestWindowWithParent(
479 lock_parent
.get(), true));
481 lock_modal_window
->Show();
482 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
483 EXPECT_TRUE(AllRootWindowsHaveLockedModalBackgrounds());
484 TestWindow::CloseTestWindow(lock_modal_window
.release());
486 // Normal system modal window while blocked, but it belongs to the normal
487 // window. Shouldn't show blocked system modal background, but normal.
488 scoped_ptr
<aura::Window
> modal_window(
489 OpenTestWindowWithParent(parent
.get(), true));
490 modal_window
->Show();
491 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
492 EXPECT_FALSE(AllRootWindowsHaveLockedModalBackgrounds());
493 TestWindow::CloseTestWindow(modal_window
.release());
494 UnblockUserSession();
495 // Here we should check the behavior of the locked system modal dialog when
496 // unlocked, but such case isn't handled very well right now.
497 // See crbug.com/157660
498 // TODO(mukai): add the test case when the bug is fixed.
502 TEST_F(SystemModalContainerLayoutManagerTest
, MultiDisplays
) {
503 if (!SupportsMultipleDisplays())
506 UpdateDisplay("500x500,500x500");
508 scoped_ptr
<aura::Window
> normal(OpenToplevelTestWindow(false));
509 normal
->SetBounds(gfx::Rect(100, 100, 50, 50));
511 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
512 EXPECT_EQ(2U, root_windows
.size());
513 aura::Window
* container1
= Shell::GetContainer(
514 root_windows
[0], ash::kShellWindowId_SystemModalContainer
);
515 aura::Window
* container2
= Shell::GetContainer(
516 root_windows
[1], ash::kShellWindowId_SystemModalContainer
);
518 scoped_ptr
<aura::Window
> modal1(
519 OpenTestWindowWithParent(container1
, true));
520 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
521 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
523 scoped_ptr
<aura::Window
> modal11(
524 OpenTestWindowWithParent(container1
, true));
525 EXPECT_TRUE(wm::IsActiveWindow(modal11
.get()));
527 scoped_ptr
<aura::Window
> modal2(
528 OpenTestWindowWithParent(container2
, true));
529 EXPECT_TRUE(wm::IsActiveWindow(modal2
.get()));
531 // Sanity check if they're on the correct containers.
532 EXPECT_EQ(container1
, modal1
->parent());
533 EXPECT_EQ(container1
, modal11
->parent());
534 EXPECT_EQ(container2
, modal2
->parent());
536 TestWindow::CloseTestWindow(modal2
.release());
537 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
538 EXPECT_TRUE(wm::IsActiveWindow(modal11
.get()));
540 TestWindow::CloseTestWindow(modal11
.release());
541 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
542 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
544 UpdateDisplay("500x500");
545 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
546 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
548 UpdateDisplay("500x500,600x600");
549 EXPECT_TRUE(AllRootWindowsHaveModalBackgrounds());
550 EXPECT_TRUE(wm::IsActiveWindow(modal1
.get()));
552 // No more modal screen.
554 TestWindow::CloseTestWindow(modal1
.release());
555 EXPECT_FALSE(AllRootWindowsHaveModalBackgrounds());
556 EXPECT_TRUE(wm::IsActiveWindow(normal
.get()));
559 // Test that with the visible keyboard, an existing system modal dialog gets
560 // positioned into the visible area.
561 TEST_F(SystemModalContainerLayoutManagerTest
,
562 SystemModalDialogGetPushedFromKeyboard
) {
563 const gfx::Rect
& container_bounds
= GetModalContainer()->bounds();
564 // Place the window at the bottom of the screen.
565 gfx::Size
modal_size(100, 100);
566 gfx::Point modal_origin
= gfx::Point(
567 (container_bounds
.right() - modal_size
.width()) / 2, // X centered
568 container_bounds
.bottom() - modal_size
.height()); // at bottom
569 gfx::Rect modal_bounds
= gfx::Rect(modal_origin
, modal_size
);
571 // Create a modal window.
572 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
573 scoped_ptr
<aura::Window
> modal_window(
574 OpenTestWindowWithParent(parent
.get(), true));
575 modal_window
->SetBounds(modal_bounds
);
577 modal_window
->Show();
579 EXPECT_EQ(modal_bounds
.ToString(), modal_window
->bounds().ToString());
581 // The keyboard gets shown and the dialog should get pushed.
583 EXPECT_NE(modal_bounds
.ToString(), modal_window
->bounds().ToString());
584 EXPECT_GT(modal_bounds
.y(), modal_window
->bounds().y());
585 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
586 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
588 // After the keyboard is gone, the window will remain where it was.
590 EXPECT_NE(modal_bounds
.ToString(), modal_window
->bounds().ToString());
591 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
592 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
595 // Test that windows will not get cropped through the visible virtual keyboard -
597 TEST_F(SystemModalContainerLayoutManagerTest
,
598 SystemModalDialogGetPushedButNotCroppedFromKeyboard
) {
599 const gfx::Rect
& container_bounds
= GetModalContainer()->bounds();
600 const gfx::Size screen_size
= Shell::GetPrimaryRootWindow()->bounds().size();
601 // Place the window at the bottom of the screen.
602 gfx::Size
modal_size(100, screen_size
.height() - 70);
603 gfx::Point modal_origin
= gfx::Point(
604 (container_bounds
.right() - modal_size
.width()) / 2, // X centered
605 container_bounds
.bottom() - modal_size
.height()); // at bottom
606 gfx::Rect modal_bounds
= gfx::Rect(modal_origin
, modal_size
);
608 // Create a modal window.
609 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
610 scoped_ptr
<aura::Window
> modal_window(
611 OpenTestWindowWithParent(parent
.get(), true));
612 modal_window
->SetBounds(modal_bounds
);
614 modal_window
->Show();
616 EXPECT_EQ(modal_bounds
.ToString(), modal_window
->bounds().ToString());
618 // The keyboard gets shown and the dialog should get pushed up, but not get
619 // cropped (and aligned to the top).
621 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
622 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
623 EXPECT_EQ(0, modal_window
->bounds().y());
628 // Test that windows will not get cropped through the visible virtual keyboard -
630 TEST_F(SystemModalContainerLayoutManagerTest
,
631 SystemModalDialogGetPushedButNotCroppedFromKeyboardIfNotCentered
) {
632 const gfx::Size screen_size
= Shell::GetPrimaryRootWindow()->bounds().size();
633 // Place the window at the bottom of the screen.
634 gfx::Size
modal_size(100, screen_size
.height() - 70);
635 gfx::Point modal_origin
= gfx::Point(10, 20);
636 gfx::Rect modal_bounds
= gfx::Rect(modal_origin
, modal_size
);
638 // Create a modal window.
639 scoped_ptr
<aura::Window
> parent(OpenToplevelTestWindow(false));
640 scoped_ptr
<aura::Window
> modal_window(
641 OpenTestWindowWithParent(parent
.get(), true));
642 modal_window
->SetBounds(modal_bounds
);
644 modal_window
->Show();
646 EXPECT_EQ(modal_bounds
.ToString(), modal_window
->bounds().ToString());
648 // The keyboard gets shown and the dialog should get pushed up, but not get
649 // cropped (and aligned to the top).
651 EXPECT_EQ(modal_size
.ToString(), modal_window
->bounds().size().ToString());
652 EXPECT_EQ(modal_origin
.x(), modal_window
->bounds().x());
653 EXPECT_EQ(0, modal_window
->bounds().y());