Upstream version 6.35.121.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 setting the bounds of a snapped window keeps its snapped.
134 TEST_F(WindowStateTest, SnapWindowSetBounds) {
135   if (!SupportsHostWindowResize())
136     return;
137
138   UpdateDisplay("0+0-900x600");
139   const gfx::Rect kWorkAreaBounds =
140       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
141
142   scoped_ptr<aura::Window> window(
143       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
144   WindowState* window_state = GetWindowState(window.get());
145   const WMEvent snap_left(WM_EVENT_SNAP_LEFT);
146   window_state->OnWMEvent(&snap_left);
147   EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
148   gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
149                                  kWorkAreaBounds.y(),
150                                  kWorkAreaBounds.width() / 2,
151                                  kWorkAreaBounds.height());
152   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
153
154   // Snapped windows can have any width.
155   expected.set_width(500);
156   window->SetBounds(gfx::Rect(10, 10, 500, 300));
157   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
158   EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
159 }
160
161 // Test that snapping left/right preserves the restore bounds.
162 TEST_F(WindowStateTest, RestoreBounds) {
163   scoped_ptr<aura::Window> window(
164       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
165   WindowState* window_state = GetWindowState(window.get());
166
167   EXPECT_TRUE(window_state->IsNormalStateType());
168
169   // 1) Start with restored window with restore bounds set.
170   gfx::Rect restore_bounds = window->GetBoundsInScreen();
171   restore_bounds.set_width(restore_bounds.width() + 1);
172   window_state->SetRestoreBoundsInScreen(restore_bounds);
173   const WMEvent snap_left(WM_EVENT_SNAP_LEFT);
174   window_state->OnWMEvent(&snap_left);
175   const WMEvent snap_right(WM_EVENT_SNAP_RIGHT);
176   window_state->OnWMEvent(&snap_right);
177   EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
178   EXPECT_EQ(restore_bounds.ToString(),
179             window_state->GetRestoreBoundsInScreen().ToString());
180   window_state->Restore();
181   EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
182
183   // 2) Start with restored bounds set as a result of maximizing the window.
184   window_state->Maximize();
185   gfx::Rect maximized_bounds = window->GetBoundsInScreen();
186   EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString());
187   EXPECT_EQ(restore_bounds.ToString(),
188             window_state->GetRestoreBoundsInScreen().ToString());
189
190   window_state->OnWMEvent(&snap_left);
191   EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
192   EXPECT_NE(maximized_bounds.ToString(),
193             window->GetBoundsInScreen().ToString());
194   EXPECT_EQ(restore_bounds.ToString(),
195             window_state->GetRestoreBoundsInScreen().ToString());
196
197   window_state->Restore();
198   EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
199 }
200
201 // Test that maximizing an auto managed window, then snapping it puts the window
202 // at the snapped bounds and not at the auto-managed (centered) bounds.
203 TEST_F(WindowStateTest, AutoManaged) {
204   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
205   WindowState* window_state = GetWindowState(window.get());
206   window_state->set_window_position_managed(true);
207   window->Hide();
208   window->SetBounds(gfx::Rect(100, 100, 100, 100));
209   window->Show();
210
211   window_state->Maximize();
212   const WMEvent snap_right(WM_EVENT_SNAP_RIGHT);
213   window_state->OnWMEvent(&snap_right);
214
215   const gfx::Rect kWorkAreaBounds =
216       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
217   gfx::Rect expected_snapped_bounds(
218       kWorkAreaBounds.x() + kWorkAreaBounds.width() / 2,
219       kWorkAreaBounds.y(),
220       kWorkAreaBounds.width() / 2,
221       kWorkAreaBounds.height());
222   EXPECT_EQ(expected_snapped_bounds.ToString(),
223             window->GetBoundsInScreen().ToString());
224
225   // The window should still be auto managed despite being right maximized.
226   EXPECT_TRUE(window_state->window_position_managed());
227 }
228
229 // Test that the replacement of a State object works as expected.
230 TEST_F(WindowStateTest, SimpleStateSwap) {
231   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
232   WindowState* window_state = GetWindowState(window.get());
233   EXPECT_FALSE(window_state->IsMaximized());
234   window_state->SetStateObject(
235       scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState(
236           window_state->GetStateType())));
237   EXPECT_TRUE(window_state->IsMaximized());
238 }
239
240 // Test that the replacement of a state object, following a restore with the
241 // original one restores the window to its original state.
242 TEST_F(WindowStateTest, StateSwapRestore) {
243   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
244   WindowState* window_state = GetWindowState(window.get());
245   EXPECT_FALSE(window_state->IsMaximized());
246   scoped_ptr<WindowState::State> old(window_state->SetStateObject(
247       scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState(
248           window_state->GetStateType()))).Pass());
249   EXPECT_TRUE(window_state->IsMaximized());
250   window_state->SetStateObject(old.Pass());
251   EXPECT_FALSE(window_state->IsMaximized());
252 }
253
254 // TODO(skuhne): Add more unit test to verify the correctness for the restore
255 // operation.
256
257 }  // namespace wm
258 }  // namespace ash