Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / wm / window_state_unittest.cc
1 // Copyright 2014 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_state.h"
6
7 #include "ash/screen_util.h"
8 #include "ash/shell.h"
9 #include "ash/test/ash_test_base.h"
10 #include "ash/wm/window_state.h"
11 #include "ash/wm/wm_event.h"
12 #include "ui/aura/test/test_window_delegate.h"
13 #include "ui/aura/window.h"
14
15 namespace ash {
16 namespace wm {
17 namespace {
18
19 class AlwaysMaximizeTestState : public WindowState::State {
20  public:
21   explicit AlwaysMaximizeTestState(WindowStateType initial_state_type)
22       : state_type_(initial_state_type) {}
23   virtual ~AlwaysMaximizeTestState() {}
24
25   // WindowState::State overrides:
26   virtual void OnWMEvent(WindowState* window_state,
27                          const WMEvent* event) OVERRIDE {
28     // We don't do anything here.
29   }
30   virtual WindowStateType GetType() const OVERRIDE {
31     return state_type_;
32   }
33   virtual void AttachState(
34       WindowState* window_state,
35       WindowState::State* previous_state) OVERRIDE {
36     // We always maximize.
37     if (state_type_ != WINDOW_STATE_TYPE_MAXIMIZED) {
38       window_state->Maximize();
39       state_type_ = WINDOW_STATE_TYPE_MAXIMIZED;
40     }
41   }
42   virtual void DetachState(WindowState* window_state) OVERRIDE {}
43
44  private:
45   WindowStateType state_type_;
46
47   DISALLOW_COPY_AND_ASSIGN(AlwaysMaximizeTestState);
48 };
49
50 }  // namespace
51
52 typedef test::AshTestBase WindowStateTest;
53
54 // Test that a window gets properly snapped to the display's edges in a
55 // multi monitor environment.
56 TEST_F(WindowStateTest, SnapWindowBasic) {
57   if (!SupportsMultipleDisplays())
58     return;
59
60   UpdateDisplay("0+0-500x400, 0+500-600x400");
61   const gfx::Rect kPrimaryDisplayWorkAreaBounds =
62       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
63   const gfx::Rect kSecondaryDisplayWorkAreaBounds =
64       ScreenUtil::GetSecondaryDisplay().work_area();
65
66   scoped_ptr<aura::Window> window(
67       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
68   WindowState* window_state = GetWindowState(window.get());
69   const WMEvent snap_left(WM_EVENT_SNAP_LEFT);
70   window_state->OnWMEvent(&snap_left);
71   gfx::Rect expected = gfx::Rect(
72       kPrimaryDisplayWorkAreaBounds.x(),
73       kPrimaryDisplayWorkAreaBounds.y(),
74       kPrimaryDisplayWorkAreaBounds.width() / 2,
75       kPrimaryDisplayWorkAreaBounds.height());
76   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
77
78   const WMEvent snap_right(WM_EVENT_SNAP_RIGHT);
79   window_state->OnWMEvent(&snap_right);
80   expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width());
81   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
82
83   // Move the window to the secondary display.
84   window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
85                             ScreenUtil::GetSecondaryDisplay());
86
87   window_state->OnWMEvent(&snap_right);
88   expected = gfx::Rect(
89       kSecondaryDisplayWorkAreaBounds.x() +
90           kSecondaryDisplayWorkAreaBounds.width() / 2,
91       kSecondaryDisplayWorkAreaBounds.y(),
92       kSecondaryDisplayWorkAreaBounds.width() / 2,
93       kSecondaryDisplayWorkAreaBounds.height());
94   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
95
96   window_state->OnWMEvent(&snap_left);
97   expected.set_x(kSecondaryDisplayWorkAreaBounds.x());
98   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
99 }
100
101 // Test how the minimum and maximum size specified by the aura::WindowDelegate
102 // affect snapping.
103 TEST_F(WindowStateTest, SnapWindowMinimumSize) {
104   if (!SupportsHostWindowResize())
105     return;
106
107   UpdateDisplay("0+0-600x900");
108   const gfx::Rect kWorkAreaBounds =
109       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
110
111   aura::test::TestWindowDelegate delegate;
112   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
113       &delegate, -1, gfx::Rect(0, 100, kWorkAreaBounds.width() - 1, 100)));
114
115   // It should be possible to snap a window with a minimum size.
116   delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0));
117   WindowState* window_state = GetWindowState(window.get());
118   EXPECT_TRUE(window_state->CanSnap());
119   const WMEvent snap_right(WM_EVENT_SNAP_RIGHT);
120   window_state->OnWMEvent(&snap_right);
121   gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1,
122                                  kWorkAreaBounds.y(),
123                                  kWorkAreaBounds.width() - 1,
124                                  kWorkAreaBounds.height());
125   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
126
127   // It should not be possible to snap a window with a maximum size.
128   delegate.set_minimum_size(gfx::Size());
129   delegate.set_maximum_size(gfx::Size(kWorkAreaBounds.width() - 1, INT_MAX));
130   EXPECT_FALSE(window_state->CanSnap());
131 }
132
133 // Test that the minimum size specified by aura::WindowDelegate gets respected.
134 TEST_F(WindowStateTest, TestRespectMinimumSize) {
135   if (!SupportsHostWindowResize())
136     return;
137
138   UpdateDisplay("0+0-1024x768");
139
140   aura::test::TestWindowDelegate delegate;
141   const gfx::Size minimum_size(gfx::Size(500, 300));
142   delegate.set_minimum_size(minimum_size);
143
144   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
145       &delegate, -1, gfx::Rect(0, 100, 100, 100)));
146
147   // Check that the window has the correct minimum size.
148   EXPECT_EQ(minimum_size.ToString(), window->bounds().size().ToString());
149
150   // Set the size to something bigger - that should work.
151   gfx::Rect bigger_bounds(700, 500, 700, 500);
152   window->SetBounds(bigger_bounds);
153   EXPECT_EQ(bigger_bounds.ToString(), window->bounds().ToString());
154
155   // Set the size to something smaller - that should only resize to the smallest
156   // possible size.
157   gfx::Rect smaller_bounds(700, 500, 100, 100);
158   window->SetBounds(smaller_bounds);
159   EXPECT_EQ(minimum_size.ToString(), window->bounds().size().ToString());
160 }
161
162 // Test that the minimum window size specified by aura::WindowDelegate does not
163 // exceed the screen size.
164 TEST_F(WindowStateTest, TestIgnoreTooBigMinimumSize) {
165   if (!SupportsHostWindowResize())
166     return;
167
168   UpdateDisplay("0+0-1024x768");
169   const gfx::Size work_area_size =
170       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area().size();
171   const gfx::Size illegal_size(1280, 960);
172   const gfx::Rect illegal_bounds(gfx::Point(0, 0), illegal_size);
173
174   aura::test::TestWindowDelegate delegate;
175   const gfx::Size minimum_size(illegal_size);
176   delegate.set_minimum_size(minimum_size);
177
178   // The creation should force the window to respect the screen size.
179   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
180       &delegate, -1, illegal_bounds));
181   EXPECT_EQ(work_area_size.ToString(), window->bounds().size().ToString());
182
183   // Trying to set the size to something bigger then the screen size should be
184   // ignored.
185   window->SetBounds(illegal_bounds);
186   EXPECT_EQ(work_area_size.ToString(), window->bounds().size().ToString());
187
188   // Maximizing the window should not allow it to go bigger than that either.
189   WindowState* window_state = GetWindowState(window.get());
190   window_state->Maximize();
191   EXPECT_EQ(work_area_size.ToString(), window->bounds().size().ToString());
192 }
193
194 // Test that setting the bounds of a snapped window keeps its snapped.
195 TEST_F(WindowStateTest, SnapWindowSetBounds) {
196   if (!SupportsHostWindowResize())
197     return;
198
199   UpdateDisplay("0+0-900x600");
200   const gfx::Rect kWorkAreaBounds =
201       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
202
203   scoped_ptr<aura::Window> window(
204       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
205   WindowState* window_state = GetWindowState(window.get());
206   const WMEvent snap_left(WM_EVENT_SNAP_LEFT);
207   window_state->OnWMEvent(&snap_left);
208   EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
209   gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
210                                  kWorkAreaBounds.y(),
211                                  kWorkAreaBounds.width() / 2,
212                                  kWorkAreaBounds.height());
213   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
214
215   // Snapped windows can have any width.
216   expected.set_width(500);
217   window->SetBounds(gfx::Rect(10, 10, 500, 300));
218   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
219   EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
220 }
221
222 // Test that snapping left/right preserves the restore bounds.
223 TEST_F(WindowStateTest, RestoreBounds) {
224   scoped_ptr<aura::Window> window(
225       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
226   WindowState* window_state = GetWindowState(window.get());
227
228   EXPECT_TRUE(window_state->IsNormalStateType());
229
230   // 1) Start with restored window with restore bounds set.
231   gfx::Rect restore_bounds = window->GetBoundsInScreen();
232   restore_bounds.set_width(restore_bounds.width() + 1);
233   window_state->SetRestoreBoundsInScreen(restore_bounds);
234   const WMEvent snap_left(WM_EVENT_SNAP_LEFT);
235   window_state->OnWMEvent(&snap_left);
236   const WMEvent snap_right(WM_EVENT_SNAP_RIGHT);
237   window_state->OnWMEvent(&snap_right);
238   EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
239   EXPECT_EQ(restore_bounds.ToString(),
240             window_state->GetRestoreBoundsInScreen().ToString());
241   window_state->Restore();
242   EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
243
244   // 2) Start with restored bounds set as a result of maximizing the window.
245   window_state->Maximize();
246   gfx::Rect maximized_bounds = window->GetBoundsInScreen();
247   EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString());
248   EXPECT_EQ(restore_bounds.ToString(),
249             window_state->GetRestoreBoundsInScreen().ToString());
250
251   window_state->OnWMEvent(&snap_left);
252   EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
253   EXPECT_NE(maximized_bounds.ToString(),
254             window->GetBoundsInScreen().ToString());
255   EXPECT_EQ(restore_bounds.ToString(),
256             window_state->GetRestoreBoundsInScreen().ToString());
257
258   window_state->Restore();
259   EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
260 }
261
262 // Test that maximizing an auto managed window, then snapping it puts the window
263 // at the snapped bounds and not at the auto-managed (centered) bounds.
264 TEST_F(WindowStateTest, AutoManaged) {
265   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
266   WindowState* window_state = GetWindowState(window.get());
267   window_state->set_window_position_managed(true);
268   window->Hide();
269   window->SetBounds(gfx::Rect(100, 100, 100, 100));
270   window->Show();
271
272   window_state->Maximize();
273   const WMEvent snap_right(WM_EVENT_SNAP_RIGHT);
274   window_state->OnWMEvent(&snap_right);
275
276   const gfx::Rect kWorkAreaBounds =
277       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
278   gfx::Rect expected_snapped_bounds(
279       kWorkAreaBounds.x() + kWorkAreaBounds.width() / 2,
280       kWorkAreaBounds.y(),
281       kWorkAreaBounds.width() / 2,
282       kWorkAreaBounds.height());
283   EXPECT_EQ(expected_snapped_bounds.ToString(),
284             window->GetBoundsInScreen().ToString());
285
286   // The window should still be auto managed despite being right maximized.
287   EXPECT_TRUE(window_state->window_position_managed());
288 }
289
290 // Test that the replacement of a State object works as expected.
291 TEST_F(WindowStateTest, SimpleStateSwap) {
292   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
293   WindowState* window_state = GetWindowState(window.get());
294   EXPECT_FALSE(window_state->IsMaximized());
295   window_state->SetStateObject(
296       scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState(
297           window_state->GetStateType())));
298   EXPECT_TRUE(window_state->IsMaximized());
299 }
300
301 // Test that the replacement of a state object, following a restore with the
302 // original one restores the window to its original state.
303 TEST_F(WindowStateTest, StateSwapRestore) {
304   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
305   WindowState* window_state = GetWindowState(window.get());
306   EXPECT_FALSE(window_state->IsMaximized());
307   scoped_ptr<WindowState::State> old(window_state->SetStateObject(
308       scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState(
309           window_state->GetStateType()))).Pass());
310   EXPECT_TRUE(window_state->IsMaximized());
311   window_state->SetStateObject(old.Pass());
312   EXPECT_FALSE(window_state->IsMaximized());
313 }
314
315 // TODO(skuhne): Add more unit test to verify the correctness for the restore
316 // operation.
317
318 }  // namespace wm
319 }  // namespace ash