1// Copyright 2013 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 "ash/wm/window_positioner.h"
6
7#include "ash/shell.h"
8#include "ash/shell/toplevel_window.h"
9#include "ash/test/ash_test_base.h"
10#include "ash/wm/window_positioner.h"
11#include "ash/wm/window_state.h"
12#include "ui/aura/window_event_dispatcher.h"
13#include "ui/gfx/screen.h"
14#include "ui/views/widget/widget.h"
15#include "ui/views/widget/widget_delegate.h"
16
17namespace ash {
18
19typedef test::AshTestBase WindowPositionerTest;
20
21TEST_F(WindowPositionerTest, OpenMaximizedWindowOnSecondDisplay) {
22  if (!SupportsMultipleDisplays())
23    return;
24  // Tests that for a screen that is narrower than kForceMaximizeWidthLimit
25  // a new window gets maximized.
26  UpdateDisplay("400x400,500x500");
27  Shell::GetInstance()->set_target_root_window(
28      Shell::GetAllRootWindows()[1]);
29  shell::ToplevelWindow::CreateParams params;
30  params.can_resize = true;
31  params.can_maximize = true;
32  views::Widget* widget =
33      shell::ToplevelWindow::CreateToplevelWindow(params);
34  EXPECT_EQ("400,0 500x453", widget->GetWindowBoundsInScreen().ToString());
35}
36
37TEST_F(WindowPositionerTest, OpenDefaultWindowOnSecondDisplay) {
38  if (!SupportsMultipleDisplays())
39    return;
40#if defined(OS_WIN)
41  ash::WindowPositioner::SetMaximizeFirstWindow(true);
42#endif
43  UpdateDisplay("400x400,1400x900");
44  aura::Window* second_root_window = Shell::GetAllRootWindows()[1];
45  Shell::GetInstance()->set_target_root_window(
46      second_root_window);
47  shell::ToplevelWindow::CreateParams params;
48  params.can_resize = true;
49  params.can_maximize = true;
50  views::Widget* widget =
51      shell::ToplevelWindow::CreateToplevelWindow(params);
52  gfx::Rect bounds = widget->GetWindowBoundsInScreen();
53#if defined(OS_WIN)
54  EXPECT_TRUE(widget->IsMaximized());
55#else
56  // The window should be in the 2nd display with the default size.
57  EXPECT_EQ("300x300", bounds.size().ToString());
58#endif
59  EXPECT_TRUE(Shell::GetScreen()->GetDisplayNearestWindow(
60      second_root_window).bounds().Contains(bounds));
61}
62
63// Tests that second window inherits first window's maximized state as well as
64// its restore bounds.
65TEST_F(WindowPositionerTest, SecondMaximizedWindowHasProperRestoreSize) {
66#if defined(OS_WIN)
67  ash::WindowPositioner::SetMaximizeFirstWindow(true);
68#endif
69  UpdateDisplay("1400x900");
70  shell::ToplevelWindow::CreateParams params;
71  params.can_resize = true;
72  params.can_maximize = true;
73  views::Widget* widget1 =
74      shell::ToplevelWindow::CreateToplevelWindow(params);
75  gfx::Rect bounds = widget1->GetWindowBoundsInScreen();
76
77#if !defined(OS_WIN)
78  // The window should have default size.
79  EXPECT_FALSE(widget1->IsMaximized());
80  EXPECT_EQ("300x300", bounds.size().ToString());
81  widget1->Maximize();
82#endif
83  // The window should be maximized.
84  bounds = widget1->GetWindowBoundsInScreen();
85  EXPECT_TRUE(widget1->IsMaximized());
86  EXPECT_EQ("0,0 1400x853", bounds.ToString());
87
88  // Create another window
89  views::Widget* widget2 =
90      shell::ToplevelWindow::CreateToplevelWindow(params);
91
92  // The second window should be maximized.
93  bounds = widget2->GetWindowBoundsInScreen();
94  EXPECT_TRUE(widget2->IsMaximized());
95  EXPECT_EQ("0,0 1400x853", bounds.ToString());
96
97  widget2->Restore();
98  // Second window's restored size should be set to default size.
99  bounds = widget2->GetWindowBoundsInScreen();
100  EXPECT_EQ("300x300", bounds.size().ToString());
101}
102
103namespace {
104
105// A WidgetDelegate that returns the out of display saved bounds.
106class OutOfDisplayDelegate : public views::WidgetDelegate {
107 public:
108  explicit OutOfDisplayDelegate(views::Widget* widget) : widget_(widget) {}
109  virtual ~OutOfDisplayDelegate() {}
110
111  // Overridden from WidgetDelegate:
112  virtual void DeleteDelegate() OVERRIDE {
113    delete this;
114  }
115  virtual views::Widget* GetWidget() OVERRIDE {
116    return widget_;
117  }
118  virtual const views::Widget* GetWidget() const OVERRIDE {
119    return widget_;
120  }
121  virtual bool GetSavedWindowPlacement(
122      const views::Widget* widget,
123      gfx::Rect* bounds,
124      ui::WindowShowState* show_state) const OVERRIDE {
125    bounds->SetRect(450, 10, 100, 100);
126    *show_state = ui::SHOW_STATE_NORMAL;
127    return true;
128  }
129
130 private:
131  views::Widget* widget_;
132
133  DISALLOW_COPY_AND_ASSIGN(OutOfDisplayDelegate);
134};
135
136}  // namespace
137
138TEST_F(WindowPositionerTest, EnsureMinimumVisibility) {
139  if (!SupportsHostWindowResize())
140    return;
141
142  UpdateDisplay("400x400");
143  views::Widget* widget = new views::Widget();
144  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
145  params.delegate = new OutOfDisplayDelegate(widget);
146  params.context = Shell::GetPrimaryRootWindow();
147  widget->Init(params);
148  widget->SetBounds(gfx::Rect(450,10, 100, 100));
149  wm::GetWindowState(widget->GetNativeView())->set_minimum_visibility(true);
150  widget->Show();
151  // Make sure the bounds is adjusted to be inside the work area.
152  EXPECT_EQ("390,10 100x100", widget->GetWindowBoundsInScreen().ToString());
153  widget->CloseNow();
154}
155
156}  // namespace
157