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