- add sources.
[platform/framework/web/crosswalk.git] / src / ash / wm / workspace / snap_sizer_unittest.cc
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/workspace/snap_sizer.h"
6
7 #include "ash/ash_switches.h"
8 #include "ash/screen_ash.h"
9 #include "ash/shell.h"
10 #include "ash/test/ash_test_base.h"
11 #include "ash/wm/window_state.h"
12 #include "ash/wm/window_util.h"
13 #include "base/command_line.h"
14 #include "ui/aura/root_window.h"
15 #include "ui/aura/test/test_window_delegate.h"
16 #include "ui/aura/window.h"
17 #include "ui/gfx/screen.h"
18
19 namespace ash {
20
21 typedef test::AshTestBase SnapSizerTest;
22
23 using internal::SnapSizer;
24
25 // Test that a window gets properly snapped to the display's edges in a
26 // multi monitor environment.
27 TEST_F(SnapSizerTest, MultipleDisplays) {
28   if (!SupportsMultipleDisplays())
29     return;
30
31   UpdateDisplay("0+0-500x400, 0+500-600x400");
32   const gfx::Rect kPrimaryDisplayWorkAreaBounds =
33       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
34   const gfx::Rect kSecondaryDisplayWorkAreaBounds =
35       ScreenAsh::GetSecondaryDisplay().work_area();
36
37   scoped_ptr<aura::Window> window(
38       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
39   wm::WindowState* window_state = wm::GetWindowState(window.get());
40   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
41   gfx::Rect expected = gfx::Rect(
42       kPrimaryDisplayWorkAreaBounds.x(),
43       kPrimaryDisplayWorkAreaBounds.y(),
44       window->bounds().width(), // No expectation for the width.
45       kPrimaryDisplayWorkAreaBounds.height());
46   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
47
48   SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
49   // The width should not change when a window switches from being snapped to
50   // the left edge to being snapped to the right edge.
51   expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width());
52   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
53
54   // Move the window to the secondary display.
55   window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
56                             ScreenAsh::GetSecondaryDisplay());
57
58   SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
59   expected = gfx::Rect(
60       kSecondaryDisplayWorkAreaBounds.right() - window->bounds().width(),
61       kSecondaryDisplayWorkAreaBounds.y(),
62       window->bounds().width(),  // No expectation for the width.
63       kSecondaryDisplayWorkAreaBounds.height());
64   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
65
66   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
67   // The width should not change when a window switches from being snapped to
68   // the right edge to being snapped to the left edge.
69   expected.set_x(kSecondaryDisplayWorkAreaBounds.x());
70   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
71 }
72
73 // Test how the minimum and maximum size specified by the aura::WindowDelegate
74 // affect snapping.
75 TEST_F(SnapSizerTest, MinimumSize) {
76   if (!SupportsHostWindowResize())
77     return;
78
79   UpdateDisplay("0+0-600x800");
80   const gfx::Rect kWorkAreaBounds =
81       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
82
83   aura::test::TestWindowDelegate delegate;
84   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
85       &delegate, -1, gfx::Rect(0, 100, kWorkAreaBounds.width() - 1, 100)));
86
87   // It should be possible to snap a window with a minimum size.
88   delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0));
89   wm::WindowState* window_state = wm::GetWindowState(window.get());
90   EXPECT_TRUE(window_state->CanSnap());
91   SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
92   gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1,
93                                  kWorkAreaBounds.y(),
94                                  kWorkAreaBounds.width() - 1,
95                                  kWorkAreaBounds.height());
96   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
97
98   // It should not be possible to snap a window with a maximum size.
99   delegate.set_minimum_size(gfx::Size());
100   delegate.set_maximum_size(gfx::Size(kWorkAreaBounds.width() - 1, INT_MAX));
101   EXPECT_FALSE(window_state->CanSnap());
102 }
103
104 // Test that repeadedly calling SnapSizer::SnapWindow() steps through the ideal
105 // widths in descending order as well as 90% and 50% of the work area's width.
106 TEST_F(SnapSizerTest, StepThroughSizes) {
107   if (!SupportsHostWindowResize())
108     return;
109
110   UpdateDisplay("0+0-1024x800");
111   const gfx::Rect kWorkAreaBounds =
112       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
113
114   scoped_ptr<aura::Window> window(
115       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
116   wm::WindowState* window_state = wm::GetWindowState(window.get());
117
118   // Make sure that the work area is the size we expect it to be.
119   EXPECT_GT(kWorkAreaBounds.width() * 0.9, 768);
120
121   // The first width should be 1024 * 0.9 because the larger ideal widths
122   // (1280, 1024) > 1024 * 0.9.
123   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
124   gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
125                                  kWorkAreaBounds.y(),
126                                  kWorkAreaBounds.width() * 0.9,
127                                  kWorkAreaBounds.height());
128   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
129
130   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
131   expected.set_width(768);
132   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
133
134   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
135   expected.set_width(640);
136   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
137
138   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
139   expected.set_width(kWorkAreaBounds.width() * 0.5);
140   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
141
142   // Wrap around.
143   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
144   expected.set_width(kWorkAreaBounds.width() * 0.9);
145   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
146 }
147
148 // Tests the SnapSizer's target bounds when resizing is disabled.
149 TEST_F(SnapSizerTest, Default) {
150   if (!SupportsHostWindowResize())
151     return;
152
153   scoped_ptr<aura::Window> window(
154       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
155   SnapSizer sizer(wm::GetWindowState(window.get()), gfx::Point(),
156                   SnapSizer::LEFT_EDGE, SnapSizer::OTHER_INPUT);
157
158   // For small workspace widths, we should snap to 90% of the workspace width
159   // because it is the largest width the window can snap to.
160   UpdateDisplay("0+0-800x600");
161   sizer.SelectDefaultSizeAndDisableResize();
162
163   gfx::Rect work_area =
164       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
165   gfx::Rect expected(work_area);
166   expected.set_width(work_area.width() * 0.9);
167   EXPECT_EQ(expected.ToString(),
168             ScreenAsh::ConvertRectToScreen(window->parent(),
169                                            sizer.target_bounds()).ToString());
170
171   // If the largest width the window can snap to is between 1024 and 1280, we
172   // should snap to 1024.
173   UpdateDisplay("0+0-1280x800");
174   sizer.SelectDefaultSizeAndDisableResize();
175   sizer.SnapWindowToTargetBounds();
176   EXPECT_EQ(1024, window->bounds().width());
177
178   // We should snap to a width of 50% of the work area it is the largest width
179   // the window can snap to.
180   UpdateDisplay("0+0-2560x1080");
181   work_area = ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
182   sizer.SelectDefaultSizeAndDisableResize();
183   sizer.SnapWindowToTargetBounds();
184   EXPECT_EQ(work_area.width() / 2, window->bounds().width());
185 }
186
187 // Test that the window only snaps to 50% of the work area width when using the
188 // alternate caption button style.
189 TEST_F(SnapSizerTest, AlternateFrameCaptionButtonStyle) {
190   if (!SupportsHostWindowResize())
191     return;
192
193   CommandLine::ForCurrentProcess()->AppendSwitch(
194       ash::switches::kAshEnableAlternateFrameCaptionButtonStyle);
195   ASSERT_TRUE(ash::switches::UseAlternateFrameCaptionButtonStyle());
196
197   UpdateDisplay("0+0-800x600");
198   const gfx::Rect kWorkAreaBounds =
199       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
200
201   scoped_ptr<aura::Window> window(
202       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
203   wm::WindowState* window_state = wm::GetWindowState(window.get());
204   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
205   gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(),
206                                  kWorkAreaBounds.y(),
207                                  kWorkAreaBounds.width() / 2,
208                                  kWorkAreaBounds.height());
209   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
210
211   // Because a window can only be snapped to one size when using the alternate
212   // caption button style, a second call to SnapSizer::SnapWindow() should have
213   // no effect.
214   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
215   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
216
217   // It should still be possible to switch a window from being snapped to the
218   // left edge to being snapped to the right edge.
219   SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
220   expected.set_x(kWorkAreaBounds.right() - expected.width());
221   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
222
223   // If resizing is disabled, the window should be snapped to 50% too.
224   SnapSizer sizer(window_state, gfx::Point(), SnapSizer::RIGHT_EDGE,
225       SnapSizer::OTHER_INPUT);
226   sizer.SelectDefaultSizeAndDisableResize();
227   sizer.SnapWindowToTargetBounds();
228   EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString());
229 }
230
231 // Test that snapping left/right preserves the restore bounds.
232 TEST_F(SnapSizerTest, RestoreBounds) {
233   scoped_ptr<aura::Window> window(
234       CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
235   wm::WindowState* window_state = wm::GetWindowState(window.get());
236
237   EXPECT_TRUE(window_state->IsNormalShowState());
238
239   // 1) Start with restored window with restore bounds set.
240   gfx::Rect restore_bounds = window->GetBoundsInScreen();
241   restore_bounds.set_width(restore_bounds.width() + 1);
242   window_state->SetRestoreBoundsInScreen(restore_bounds);
243   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
244   SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
245   EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
246   EXPECT_EQ(restore_bounds.ToString(),
247             window_state->GetRestoreBoundsInScreen().ToString());
248   window_state->Restore();
249   EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
250
251   // 2) Start with restored bounds set as a result of maximizing the window.
252   window_state->Maximize();
253   gfx::Rect maximized_bounds = window->GetBoundsInScreen();
254   EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString());
255   EXPECT_EQ(restore_bounds.ToString(),
256             window_state->GetRestoreBoundsInScreen().ToString());
257
258   SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE);
259   EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
260   EXPECT_NE(maximized_bounds.ToString(),
261             window->GetBoundsInScreen().ToString());
262   EXPECT_EQ(restore_bounds.ToString(),
263             window_state->GetRestoreBoundsInScreen().ToString());
264
265   window_state->Restore();
266   EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString());
267 }
268
269 // Test that maximizing an auto managed window, then snapping it puts the window
270 // at the snapped bounds and not at the auto-managed (centered) bounds.
271 TEST_F(SnapSizerTest, AutoManaged) {
272   scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
273   wm::WindowState* window_state = wm::GetWindowState(window.get());
274   window_state->set_window_position_managed(true);
275   window->Hide();
276   window->SetBounds(gfx::Rect(100, 100, 100, 100));
277   window->Show();
278
279   window_state->Maximize();
280   SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE);
281
282   const gfx::Rect kWorkAreaBounds =
283       ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
284   gfx::Rect expected_snapped_bounds(
285       kWorkAreaBounds.right() - window->bounds().width(),
286       kWorkAreaBounds.y(),
287       window->bounds().width(), // No expectation for the width.
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 }  // namespace ash