Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / window_sizer / window_sizer_ash_unittest.cc
bloba05b2bf4bacd0783b426ec45a0707d1e6def3b51
1 // Copyright (c) 2012 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.
5 #include "ash/scoped_target_root_window.h"
6 #include "ash/screen_util.h"
7 #include "ash/shell.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/test/test_shell_delegate.h"
10 #include "ash/wm/window_positioner.h"
11 #include "ash/wm/window_resizer.h"
12 #include "ash/wm/window_state.h"
13 #include "base/compiler_specific.h"
14 #include "chrome/browser/ui/ash/ash_util.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/window_sizer/window_sizer_common_unittest.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/test_browser_window_aura.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "content/public/test/render_view_test.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/aura/client/aura_constants.h"
23 #include "ui/aura/env.h"
24 #include "ui/aura/test/test_windows.h"
25 #include "ui/aura/window_event_dispatcher.h"
26 #include "ui/gfx/screen.h"
27 #include "ui/wm/public/activation_client.h"
29 typedef ash::test::AshTestBase WindowSizerAshTest;
31 namespace {
33 scoped_ptr<Browser> CreateTestBrowser(aura::Window* window,
34 const gfx::Rect& bounds,
35 Browser::CreateParams* params) {
36 if (!bounds.IsEmpty())
37 window->SetBounds(bounds);
38 scoped_ptr<Browser> browser =
39 chrome::CreateBrowserWithAuraTestWindowForParams(make_scoped_ptr(window),
40 params);
41 if (browser->is_type_tabbed() || browser->is_app()) {
42 ash::wm::GetWindowState(browser->window()->GetNativeWindow())
43 ->set_window_position_managed(true);
45 return browser.Pass();
48 } // namespace
50 // On desktop linux aura, we currently don't use the ash frame, breaking some
51 // tests which expect ash sizes: http://crbug.com/303862
52 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
53 #define MAYBE_DefaultSizeCase DISABLED_DefaultSizeCase
54 #else
55 #define MAYBE_DefaultSizeCase DefaultSizeCase
56 #endif
58 // Test that the window is sized appropriately for the first run experience
59 // where the default window bounds calculation is invoked.
60 TEST_F(WindowSizerAshTest, MAYBE_DefaultSizeCase) {
61 #if defined(OS_WIN)
62 base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kOpenAsh);
63 #endif
64 { // 4:3 monitor case, 1024x768, no taskbar
65 gfx::Rect window_bounds;
66 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(),
67 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
68 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
69 ash::WindowPositioner::kDesktopBorderSize,
70 1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
71 768 - ash::WindowPositioner::kDesktopBorderSize),
72 window_bounds);
75 { // 4:3 monitor case, 1024x768, taskbar on bottom
76 gfx::Rect window_bounds;
77 GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(),
78 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
79 &window_bounds);
80 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
81 ash::WindowPositioner::kDesktopBorderSize,
82 1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
83 taskbar_bottom_work_area.height() -
84 ash::WindowPositioner::kDesktopBorderSize),
85 window_bounds);
88 { // 4:3 monitor case, 1024x768, taskbar on right
89 gfx::Rect window_bounds;
90 GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(),
91 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
92 &window_bounds);
93 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
94 ash::WindowPositioner::kDesktopBorderSize,
95 taskbar_right_work_area.width() -
96 ash::WindowPositioner::kDesktopBorderSize * 2,
97 768 - ash::WindowPositioner::kDesktopBorderSize),
98 window_bounds);
101 { // 4:3 monitor case, 1024x768, taskbar on left
102 gfx::Rect window_bounds;
103 GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(),
104 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
105 &window_bounds);
106 EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() +
107 ash::WindowPositioner::kDesktopBorderSize,
108 ash::WindowPositioner::kDesktopBorderSize,
109 taskbar_left_work_area.width() -
110 ash::WindowPositioner::kDesktopBorderSize * 2,
111 taskbar_left_work_area.height() -
112 ash::WindowPositioner::kDesktopBorderSize),
113 window_bounds);
116 { // 4:3 monitor case, 1024x768, taskbar on top
117 gfx::Rect window_bounds;
118 GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(),
119 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
120 &window_bounds);
121 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
122 taskbar_top_work_area.y() +
123 ash::WindowPositioner::kDesktopBorderSize,
124 1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
125 taskbar_top_work_area.height() -
126 ash::WindowPositioner::kDesktopBorderSize),
127 window_bounds);
130 { // 4:3 monitor case, 1280x1024
131 gfx::Rect window_bounds;
132 GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(),
133 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
134 EXPECT_EQ(gfx::Rect((1280 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
135 ash::WindowPositioner::kDesktopBorderSize,
136 ash::WindowPositioner::kMaximumWindowWidth,
137 1024 - ash::WindowPositioner::kDesktopBorderSize),
138 window_bounds);
141 { // 4:3 monitor case, 1600x1200
142 gfx::Rect window_bounds;
143 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(),
144 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
145 EXPECT_EQ(gfx::Rect((1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
146 ash::WindowPositioner::kDesktopBorderSize,
147 ash::WindowPositioner::kMaximumWindowWidth,
148 1200 - ash::WindowPositioner::kDesktopBorderSize),
149 window_bounds);
152 { // 16:10 monitor case, 1680x1050
153 gfx::Rect window_bounds;
154 GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(),
155 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
156 EXPECT_EQ(gfx::Rect((1680 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
157 ash::WindowPositioner::kDesktopBorderSize,
158 ash::WindowPositioner::kMaximumWindowWidth,
159 1050 - ash::WindowPositioner::kDesktopBorderSize),
160 window_bounds);
163 { // 16:10 monitor case, 1920x1200
164 gfx::Rect window_bounds;
165 GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(),
166 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
167 EXPECT_EQ(gfx::Rect((1920 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
168 ash::WindowPositioner::kDesktopBorderSize,
169 ash::WindowPositioner::kMaximumWindowWidth,
170 1200 - ash::WindowPositioner::kDesktopBorderSize),
171 window_bounds);
175 // Test that the next opened window is positioned appropriately given the
176 // bounds of an existing window of the same type.
177 TEST_F(WindowSizerAshTest, LastWindowBoundsCase) {
178 { // normal, in the middle of the screen somewhere.
179 gfx::Rect window_bounds;
180 GetWindowBounds(
181 p1024x768, p1024x768, gfx::Rect(),
182 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
183 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
184 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
185 &window_bounds);
186 EXPECT_EQ(
187 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
188 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
189 500, 400).ToString(),
190 window_bounds.ToString());
193 { // taskbar on top.
194 gfx::Rect window_bounds;
195 GetWindowBounds(
196 p1024x768, taskbar_top_work_area, gfx::Rect(),
197 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
198 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
199 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
200 &window_bounds);
201 EXPECT_EQ(
202 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
203 std::max(kWindowTilePixels +
204 ash::WindowPositioner::kDesktopBorderSize,
205 34 /* toolbar height */),
206 500, 400).ToString(),
207 window_bounds.ToString());
210 { // Too small to satisify the minimum visibility condition.
211 gfx::Rect window_bounds;
212 GetWindowBounds(
213 p1024x768, p1024x768, gfx::Rect(),
214 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
215 ash::WindowPositioner::kDesktopBorderSize, 29, 29),
216 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
217 &window_bounds);
218 EXPECT_EQ(
219 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
220 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
221 30 /* not 29 */,
222 30 /* not 29 */).ToString(),
223 window_bounds.ToString());
227 { // Normal.
228 gfx::Rect window_bounds;
229 GetWindowBounds(
230 p1024x768, p1024x768, gfx::Rect(),
231 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
232 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
233 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
234 &window_bounds);
235 EXPECT_EQ(
236 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
237 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
238 500, 400).ToString(),
239 window_bounds.ToString());
243 // Test that the window opened is sized appropriately given persisted sizes.
244 TEST_F(WindowSizerAshTest, PersistedBoundsCase) {
245 { // normal, in the middle of the screen somewhere.
246 gfx::Rect initial_bounds(
247 ash::WindowPositioner::kDesktopBorderSize,
248 ash::WindowPositioner::kDesktopBorderSize, 500, 400);
250 gfx::Rect window_bounds;
251 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
252 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
253 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
256 { // Normal.
257 gfx::Rect initial_bounds(0, 0, 1024, 768);
259 gfx::Rect window_bounds;
260 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
261 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
262 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
265 { // normal, on non-primary monitor in negative coords.
266 gfx::Rect initial_bounds(-600, 10, 500, 400);
268 gfx::Rect window_bounds;
269 GetWindowBounds(p1024x768, p1024x768, left_s1024x768,
270 initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(),
271 &window_bounds);
272 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
275 { // normal, on non-primary monitor in negative coords.
276 gfx::Rect initial_bounds(-1024, 0, 1024, 768);
278 gfx::Rect window_bounds;
279 GetWindowBounds(p1024x768, p1024x768, left_s1024x768,
280 initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(),
281 &window_bounds);
282 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
285 { // Non-primary monitor resoultion has changed, but the monitor still
286 // completely contains the window.
288 gfx::Rect initial_bounds(1074, 50, 600, 500);
290 gfx::Rect window_bounds;
291 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
292 initial_bounds, right_s1024x768, PERSISTED, NULL,
293 gfx::Rect(), &window_bounds);
294 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
297 { // Non-primary monitor resoultion has changed, and the window is partially
298 // off-screen.
300 gfx::Rect initial_bounds(1274, 50, 600, 500);
302 gfx::Rect window_bounds;
303 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
304 initial_bounds, right_s1024x768, PERSISTED,
305 NULL, gfx::Rect(), &window_bounds);
306 EXPECT_EQ("1224,50 600x500", window_bounds.ToString());
309 { // Non-primary monitor resoultion has changed, and the window is now too
310 // large for the monitor.
312 gfx::Rect initial_bounds(1274, 50, 900, 700);
314 gfx::Rect window_bounds;
315 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
316 initial_bounds, right_s1024x768, PERSISTED,
317 NULL, gfx::Rect(), &window_bounds);
318 EXPECT_EQ("1024,0 800x600", window_bounds.ToString());
321 { // width and height too small
322 gfx::Rect window_bounds;
323 GetWindowBounds(
324 p1024x768, p1024x768, gfx::Rect(),
325 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
326 ash::WindowPositioner::kDesktopBorderSize, 29, 29),
327 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
328 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
329 ash::WindowPositioner::kDesktopBorderSize,
330 30 /* not 29 */, 30 /* not 29 */).ToString(),
331 window_bounds.ToString());
335 //////////////////////////////////////////////////////////////////////////////
336 // The following unittests have different results on Mac/non-Mac because we
337 // reposition windows aggressively on Mac. The *WithAggressiveReposition tests
338 // are run on Mac, and the *WithNonAggressiveRepositioning tests are run on
339 // other platforms.
341 TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) {
342 { // taskbar on left.
343 gfx::Rect window_bounds;
344 GetWindowBounds(
345 p1024x768, taskbar_left_work_area, gfx::Rect(),
346 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
347 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
348 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
349 &window_bounds);
350 EXPECT_EQ(
351 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
352 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
353 500, 400).ToString(),
354 window_bounds.ToString());
357 { // offset would put the new window offscreen at the bottom but the minimum
358 // visibility condition is barely satisfied without relocation.
359 gfx::Rect window_bounds;
360 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
361 gfx::Rect(10, 728, 500, 400), gfx::Rect(), LAST_ACTIVE,
362 NULL, gfx::Rect(), &window_bounds);
363 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400).ToString(),
364 window_bounds.ToString());
367 { // offset would put the new window offscreen at the bottom and the minimum
368 // visibility condition is satisified by relocation.
369 gfx::Rect window_bounds;
370 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
371 gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE,
372 NULL, gfx::Rect(), &window_bounds);
373 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels,
374 738 /* not 739 */,
375 500,
376 400).ToString(),
377 window_bounds.ToString());
380 { // offset would put the new window offscreen at the right but the minimum
381 // visibility condition is barely satisfied without relocation.
382 gfx::Rect window_bounds;
383 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
384 gfx::Rect(984, 10, 500, 400), gfx::Rect(), LAST_ACTIVE,
385 NULL, gfx::Rect(), &window_bounds);
386 EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400).ToString(),
387 window_bounds.ToString());
390 { // offset would put the new window offscreen at the right and the minimum
391 // visibility condition is satisified by relocation.
392 gfx::Rect window_bounds;
393 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
394 gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE,
395 NULL, gfx::Rect(), &window_bounds);
396 EXPECT_EQ(gfx::Rect(994 /* not 995 */,
397 10 + kWindowTilePixels,
398 500,
399 400).ToString(),
400 window_bounds.ToString());
403 { // offset would put the new window offscreen at the bottom right and the
404 // minimum visibility condition is satisified by relocation.
405 gfx::Rect window_bounds;
406 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
407 gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE,
408 NULL, gfx::Rect(), &window_bounds);
409 EXPECT_EQ(gfx::Rect(994 /* not 995 */,
410 738 /* not 739 */,
411 500,
412 400).ToString(),
413 window_bounds.ToString());
417 // On desktop linux aura, we currently don't use the ash frame, breaking some
418 // tests which expect ash sizes: http://crbug.com/303862
419 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
420 #define MAYBE_PlaceNewWindows DISABLED_PlaceNewWindows
421 #else
422 #define MAYBE_PlaceNewWindows PlaceNewWindows
423 #endif
425 // Test the placement of newly created windows.
426 TEST_F(WindowSizerAshTest, MAYBE_PlaceNewWindows) {
427 // Create a browser to pass into the GetWindowBounds function.
428 scoped_ptr<TestingProfile> profile(new TestingProfile());
429 // Creating a popup handler here to make sure it does not interfere with the
430 // existing windows.
431 Browser::CreateParams native_params(profile.get(),
432 chrome::HOST_DESKTOP_TYPE_ASH);
433 scoped_ptr<Browser> browser(
434 chrome::CreateBrowserWithTestWindowForParams(&native_params));
436 // Creating a popup handler here to make sure it does not interfere with the
437 // existing windows.
438 Browser::CreateParams params2(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH);
439 scoped_ptr<Browser> browser2(CreateTestBrowser(
440 CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), &params2));
441 BrowserWindow* browser_window = browser2->window();
443 // Creating a popup to make sure it does not interfere with the positioning.
444 Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get(),
445 chrome::HOST_DESKTOP_TYPE_ASH);
446 scoped_ptr<Browser> browser_popup(
447 CreateTestBrowser(CreateTestWindowInShellWithId(1),
448 gfx::Rect(16, 32, 128, 256), &params_popup));
450 // Creating a panel to make sure it does not interfere with the positioning.
451 Browser::CreateParams params_panel(Browser::TYPE_POPUP, profile.get(),
452 chrome::HOST_DESKTOP_TYPE_ASH);
453 scoped_ptr<Browser> browser_panel(
454 CreateTestBrowser(CreateTestWindowInShellWithId(2),
455 gfx::Rect(32, 48, 256, 512), &params_panel));
457 browser_window->Show();
458 { // Make sure that popups do not get changed.
459 gfx::Rect window_bounds;
460 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
461 gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, PERSISTED,
462 browser_popup.get(), gfx::Rect(), &window_bounds);
463 EXPECT_EQ("50,100 300x150", window_bounds.ToString());
466 browser_window->Hide();
467 { // If a window is there but not shown the persisted default should be used.
468 gfx::Rect window_bounds;
469 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
470 gfx::Rect(50, 100, 300, 150), bottom_s1600x1200,
471 PERSISTED, browser.get(), gfx::Rect(), &window_bounds);
472 EXPECT_EQ("50,100 300x150", window_bounds.ToString());
475 { // If a window is there but not shown the default should be returned.
476 gfx::Rect window_bounds;
477 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
478 gfx::Rect(), bottom_s1600x1200,
479 DEFAULT, browser.get(), gfx::Rect(), &window_bounds);
480 // Note: We need to also take the defaults maximum width into account here
481 // since that might get used if the resolution is too big.
482 EXPECT_EQ(
483 gfx::Rect(
484 std::max(ash::WindowPositioner::kDesktopBorderSize,
485 (1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2),
486 ash::WindowPositioner::kDesktopBorderSize,
487 std::min(ash::WindowPositioner::kMaximumWindowWidth,
488 1600 - 2 * ash::WindowPositioner::kDesktopBorderSize),
489 1200 - ash::WindowPositioner::kDesktopBorderSize).ToString(),
490 window_bounds.ToString());
494 // On desktop linux aura, we currently don't use the ash frame, breaking some
495 // tests which expect ash sizes: http://crbug.com/303862
496 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
497 #define MAYBE_PlaceNewBrowserWindowOnEmptyDesktop DISABLED_PlaceNewBrowserWindowOnEmptyDesktop
498 #else
499 #define MAYBE_PlaceNewBrowserWindowOnEmptyDesktop PlaceNewBrowserWindowOnEmptyDesktop
500 #endif
502 // Test the placement of newly created windows on an empty desktop.
503 // This test supplements "PlaceNewWindows" by testing the creation of a newly
504 // created browser window on an empty desktop.
505 TEST_F(WindowSizerAshTest, MAYBE_PlaceNewBrowserWindowOnEmptyDesktop) {
506 // Create a browser to pass into the GetWindowBoundsAndShowState function.
507 scoped_ptr<TestingProfile> profile(new TestingProfile());
508 Browser::CreateParams native_params(profile.get(),
509 chrome::HOST_DESKTOP_TYPE_ASH);
510 scoped_ptr<Browser> browser(
511 chrome::CreateBrowserWithTestWindowForParams(&native_params));
513 // A common screen size for Chrome OS devices where this behavior is
514 // desirable.
515 const gfx::Rect p1366x768(0, 0, 1366, 768);
517 // If there is no previous state the window should get maximized if the
518 // screen is less than or equal to our limit (1366 pixels width).
519 gfx::Rect window_bounds;
520 ui::WindowShowState out_show_state1 = ui::SHOW_STATE_DEFAULT;
521 GetWindowBoundsAndShowState(
522 p1366x768, // The screen resolution.
523 p1366x768, // The monitor work area.
524 gfx::Rect(), // The second monitor.
525 gfx::Rect(), // The (persisted) bounds.
526 p1366x768, // The overall work area.
527 ui::SHOW_STATE_NORMAL, // The persisted show state.
528 ui::SHOW_STATE_DEFAULT, // The last show state.
529 DEFAULT, // No persisted values.
530 browser.get(), // Use this browser.
531 gfx::Rect(), // Don't request valid bounds.
532 &window_bounds,
533 &out_show_state1);
534 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, out_show_state1);
536 // If there is a stored coordinate however, that should be taken instead.
537 ui::WindowShowState out_show_state2 = ui::SHOW_STATE_DEFAULT;
538 GetWindowBoundsAndShowState(
539 p1366x768, // The screen resolution.
540 p1366x768, // The monitor work area.
541 gfx::Rect(), // The second monitor.
542 gfx::Rect(50, 100, 300, 150), // The (persisted) bounds.
543 p1366x768, // The overall work area.
544 ui::SHOW_STATE_NORMAL, // The persisted show state.
545 ui::SHOW_STATE_DEFAULT, // The last show state.
546 PERSISTED, // Set the persisted values.
547 browser.get(), // Use this browser.
548 gfx::Rect(), // Don't request valid bounds.
549 &window_bounds,
550 &out_show_state2);
551 EXPECT_EQ(ui::SHOW_STATE_NORMAL, out_show_state2);
552 EXPECT_EQ("50,100 300x150", window_bounds.ToString());
554 // A larger monitor should not trigger auto-maximize.
555 ui::WindowShowState out_show_state3 = ui::SHOW_STATE_DEFAULT;
556 GetWindowBoundsAndShowState(
557 p1600x1200, // The screen resolution.
558 p1600x1200, // The monitor work area.
559 gfx::Rect(), // The second monitor.
560 gfx::Rect(), // The (persisted) bounds.
561 p1600x1200, // The overall work area.
562 ui::SHOW_STATE_NORMAL, // The persisted show state.
563 ui::SHOW_STATE_DEFAULT, // The last show state.
564 DEFAULT, // No persisted values.
565 browser.get(), // Use this browser.
566 gfx::Rect(), // Don't request valid bounds.
567 &window_bounds,
568 &out_show_state3);
569 #if defined(OS_WIN)
570 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, out_show_state3);
571 #else
572 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, out_show_state3);
573 #endif
576 #if defined(OS_CHROMEOS)
577 #define MAYBE_PlaceNewWindowsOnMultipleDisplays PlaceNewWindowsOnMultipleDisplays
578 #else
579 // No multiple displays on windows ash.
580 #define MAYBE_PlaceNewWindowsOnMultipleDisplays DISABLED_PlaceNewWindowsOnMultipleDisplays
581 #endif
583 // Test the placement of newly created windows on multiple dislays.
584 TEST_F(WindowSizerAshTest, MAYBE_PlaceNewWindowsOnMultipleDisplays) {
585 UpdateDisplay("1600x1200,1600x1200");
586 gfx::Rect primary_bounds = ash::Shell::GetInstance()->GetScreen()->
587 GetPrimaryDisplay().bounds();
588 gfx::Rect secondary_bounds = ash::ScreenUtil::GetSecondaryDisplay().bounds();
590 ash::Shell::GetInstance()->set_target_root_window(
591 ash::Shell::GetPrimaryRootWindow());
593 scoped_ptr<TestingProfile> profile(new TestingProfile());
595 // Create browser windows that are used as reference.
596 Browser::CreateParams params(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH);
597 scoped_ptr<Browser> browser(CreateTestBrowser(
598 CreateTestWindowInShellWithId(0), gfx::Rect(10, 10, 200, 200), &params));
599 BrowserWindow* browser_window = browser->window();
600 gfx::NativeWindow native_window = browser_window->GetNativeWindow();
601 browser_window->Show();
602 EXPECT_EQ(native_window->GetRootWindow(), ash::Shell::GetTargetRootWindow());
604 Browser::CreateParams another_params(profile.get(),
605 chrome::HOST_DESKTOP_TYPE_ASH);
606 scoped_ptr<Browser> another_browser(
607 CreateTestBrowser(CreateTestWindowInShellWithId(1),
608 gfx::Rect(400, 10, 300, 300), &another_params));
609 BrowserWindow* another_browser_window = another_browser->window();
610 gfx::NativeWindow another_native_window =
611 another_browser_window->GetNativeWindow();
612 another_browser_window->Show();
614 // Creating a new window to verify the new placement.
615 Browser::CreateParams new_params(profile.get(),
616 chrome::HOST_DESKTOP_TYPE_ASH);
617 scoped_ptr<Browser> new_browser(CreateTestBrowser(
618 CreateTestWindowInShellWithId(0), gfx::Rect(), &new_params));
620 // Make sure the primary root is active.
621 ASSERT_EQ(ash::Shell::GetPrimaryRootWindow(),
622 ash::Shell::GetTargetRootWindow());
624 // First new window should be in the primary.
626 gfx::Rect window_bounds;
627 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(),
628 secondary_bounds, PERSISTED, new_browser.get(), gfx::Rect(),
629 &window_bounds);
630 // TODO(oshima): Use exact bounds when the window_sizer_ash is
631 // moved to ash and changed to include the result from
632 // RearrangeVisibleWindowOnShow.
633 EXPECT_TRUE(primary_bounds.Contains(window_bounds));
636 // Move the window to the right side of the secondary display and create a new
637 // window. It should be opened then on the secondary display.
639 gfx::Display second_display = ash::Shell::GetScreen()->
640 GetDisplayNearestPoint(gfx::Point(1600 + 100,10));
641 browser_window->GetNativeWindow()->SetBoundsInScreen(
642 gfx::Rect(secondary_bounds.CenterPoint().x() - 100, 10, 200, 200),
643 second_display);
644 aura::client::GetActivationClient(native_window->GetRootWindow())
645 ->ActivateWindow(native_window);
646 EXPECT_NE(ash::Shell::GetPrimaryRootWindow(),
647 ash::Shell::GetTargetRootWindow());
648 gfx::Rect window_bounds;
649 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(),
650 secondary_bounds, PERSISTED, new_browser.get(), gfx::Rect(),
651 &window_bounds);
652 // TODO(oshima): Use exact bounds when the window_sizer_ash is
653 // moved to ash and changed to include the result from
654 // RearrangeVisibleWindowOnShow.
655 EXPECT_TRUE(secondary_bounds.Contains(window_bounds));
658 // Activate another window in the primary display and create a new window.
659 // It should be created in the primary display.
661 aura::client::GetActivationClient(another_native_window->GetRootWindow())
662 ->ActivateWindow(another_native_window);
663 EXPECT_EQ(ash::Shell::GetPrimaryRootWindow(),
664 ash::Shell::GetTargetRootWindow());
666 gfx::Rect window_bounds;
667 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(),
668 secondary_bounds, PERSISTED, new_browser.get(), gfx::Rect(),
669 &window_bounds);
670 // TODO(oshima): Use exact bounds when the window_sizer_ash is
671 // moved to ash and changed to include the result from
672 // RearrangeVisibleWindowOnShow.
673 EXPECT_TRUE(primary_bounds.Contains(window_bounds));
677 // On desktop linux aura, we currently don't use the ash frame, breaking some
678 // tests which expect ash sizes: http://crbug.com/303862
679 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
680 #define MAYBE_TestShowState DISABLED_TestShowState
681 #else
682 #define MAYBE_TestShowState TestShowState
683 #endif
685 // Test that the show state is properly returned for non default cases.
686 TEST_F(WindowSizerAshTest, MAYBE_TestShowState) {
687 scoped_ptr<TestingProfile> profile(new TestingProfile());
689 // Creating a browser & window to play with.
690 Browser::CreateParams params(Browser::TYPE_TABBED, profile.get(),
691 chrome::HOST_DESKTOP_TYPE_ASH);
692 scoped_ptr<Browser> browser(CreateTestBrowser(
693 CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), &params));
695 // Create also a popup browser since that behaves different.
696 Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get(),
697 chrome::HOST_DESKTOP_TYPE_ASH);
698 scoped_ptr<Browser> browser_popup(
699 CreateTestBrowser(CreateTestWindowInShellWithId(1),
700 gfx::Rect(16, 32, 640, 320), &params_popup));
702 // Tabbed windows should retrieve the saved window state - since there is a
703 // top window.
704 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
705 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_NORMAL,
706 BOTH, browser.get(), p1600x1200, p1600x1200));
707 // A window that is smaller than the whole work area is set to default state.
708 EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
709 GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL,
710 BOTH, browser.get(), p1280x1024, p1600x1200));
711 // A window that is sized to occupy the whole work area is maximized.
712 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
713 GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL,
714 BOTH, browser.get(), p1600x1200, p1600x1200));
715 // Non tabbed windows should always follow the window saved visibility state.
716 EXPECT_EQ(
717 ui::SHOW_STATE_MAXIMIZED,
718 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_NORMAL, BOTH,
719 browser_popup.get(), p1600x1200, p1600x1200));
720 // The non tabbed window will take the status of the last active of its kind.
721 EXPECT_EQ(
722 ui::SHOW_STATE_NORMAL,
723 GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH,
724 browser_popup.get(), p1600x1200, p1600x1200));
726 // Now create a top level window and check again for both. Only the tabbed
727 // window should follow the top level window's state.
728 // Creating a browser & window to play with.
729 Browser::CreateParams params2(Browser::TYPE_TABBED, profile.get(),
730 chrome::HOST_DESKTOP_TYPE_ASH);
731 scoped_ptr<Browser> browser2(CreateTestBrowser(
732 CreateTestWindowInShellWithId(3), gfx::Rect(16, 32, 640, 320), &params2));
734 // A tabbed window should now take the top level window state.
735 EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
736 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT,
737 BOTH, browser.get(), p1600x1200, p1600x1200));
738 // Non tabbed windows should always follow the window saved visibility state.
739 EXPECT_EQ(
740 ui::SHOW_STATE_MAXIMIZED,
741 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MINIMIZED,
742 BOTH, browser_popup.get(), p1600x1200, p1600x1200));
744 // In smaller screen resolutions we default to maximized if there is no other
745 // window visible.
746 int min_size = ash::WindowPositioner::GetForceMaximizedWidthLimit() / 2;
747 if (min_size > 0) {
748 const gfx::Rect tiny_screen(0, 0, min_size, min_size);
749 EXPECT_EQ(
750 ui::SHOW_STATE_DEFAULT,
751 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT,
752 BOTH, browser.get(), tiny_screen, tiny_screen));
753 browser->window()->Hide();
754 EXPECT_EQ(
755 ui::SHOW_STATE_MAXIMIZED,
756 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT,
757 BOTH, browser2.get(), tiny_screen, tiny_screen));
761 // Test that the default show state override behavior is properly handled.
762 TEST_F(WindowSizerAshTest, TestShowStateDefaults) {
763 // Creating a browser & window to play with.
764 scoped_ptr<TestingProfile> profile(new TestingProfile());
766 Browser::CreateParams params(Browser::TYPE_TABBED, profile.get(),
767 chrome::HOST_DESKTOP_TYPE_ASH);
768 scoped_ptr<Browser> browser(CreateTestBrowser(
769 CreateTestWindowInShellWithId(0), gfx::Rect(16, 32, 640, 320), &params));
771 // Create also a popup browser since that behaves slightly different for
772 // defaults.
773 Browser::CreateParams params_popup(Browser::TYPE_POPUP, profile.get(),
774 chrome::HOST_DESKTOP_TYPE_ASH);
775 scoped_ptr<Browser> browser_popup(
776 CreateTestBrowser(CreateTestWindowInShellWithId(1),
777 gfx::Rect(16, 32, 128, 256), &params_popup));
779 // Check that a browser creation state always get used if not given as
780 // SHOW_STATE_DEFAULT. On Windows ASH it should be SHOW_STATE_MAXIMIZED.
781 ui::WindowShowState window_show_state =
782 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED,
783 DEFAULT, browser.get(), p1600x1200, p1600x1200);
784 #if defined(OS_WIN)
785 EXPECT_EQ(window_show_state, ui::SHOW_STATE_MAXIMIZED);
786 #else
787 EXPECT_EQ(window_show_state, ui::SHOW_STATE_DEFAULT);
788 #endif
790 browser->set_initial_show_state(ui::SHOW_STATE_MINIMIZED);
791 EXPECT_EQ(
792 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED,
793 BOTH, browser.get(), p1600x1200, p1600x1200),
794 ui::SHOW_STATE_MINIMIZED);
795 browser->set_initial_show_state(ui::SHOW_STATE_NORMAL);
796 EXPECT_EQ(
797 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED,
798 BOTH, browser.get(), p1600x1200, p1600x1200),
799 ui::SHOW_STATE_NORMAL);
800 browser->set_initial_show_state(ui::SHOW_STATE_MAXIMIZED);
801 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL,
802 BOTH, browser.get(), p1600x1200, p1600x1200),
803 ui::SHOW_STATE_MAXIMIZED);
805 // Check that setting the maximized command line option is forcing the
806 // maximized state.
807 base::CommandLine::ForCurrentProcess()->AppendSwitch(
808 switches::kStartMaximized);
810 browser->set_initial_show_state(ui::SHOW_STATE_NORMAL);
811 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL,
812 BOTH, browser.get(), p1600x1200, p1600x1200),
813 ui::SHOW_STATE_MAXIMIZED);
815 // The popup should favor the initial show state over the command line.
816 EXPECT_EQ(
817 GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, BOTH,
818 browser_popup.get(), p1600x1200, p1600x1200),
819 ui::SHOW_STATE_NORMAL);
822 TEST_F(WindowSizerAshTest, DefaultStateBecomesMaximized) {
823 // Create a browser to pass into the GetWindowBounds function.
824 scoped_ptr<TestingProfile> profile(new TestingProfile());
825 Browser::CreateParams native_params(profile.get(),
826 chrome::HOST_DESKTOP_TYPE_ASH);
827 scoped_ptr<Browser> browser(
828 chrome::CreateBrowserWithTestWindowForParams(&native_params));
830 gfx::Rect display_bounds = ash::Shell::GetInstance()->GetScreen()->
831 GetPrimaryDisplay().bounds();
832 gfx::Rect specified_bounds = display_bounds;
834 // Make a window bigger than the display work area.
835 specified_bounds.Inset(-20, -20);
836 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
837 gfx::Rect bounds;
838 WindowSizer::GetBrowserWindowBoundsAndShowState(
839 std::string(), specified_bounds, browser.get(), &bounds, &show_state);
840 // The window should start maximized with its restore bounds shrunken.
841 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, show_state);
842 EXPECT_NE(display_bounds.ToString(), bounds.ToString());
843 EXPECT_TRUE(display_bounds.Contains(bounds));
845 // Make a window smaller than the display work area.
846 specified_bounds.Inset(100, 100);
847 show_state = ui::SHOW_STATE_DEFAULT;
848 WindowSizer::GetBrowserWindowBoundsAndShowState(
849 std::string(), specified_bounds, browser.get(), &bounds, &show_state);
850 // The window should start in default state.
851 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, show_state);
852 EXPECT_EQ(specified_bounds.ToString(), bounds.ToString());
855 // Test that the target root window is used as the destination of
856 // the non browser window. This differ from PersistedBoundsCase
857 // in that this uses real ash shell implementations + StateProvider
858 // TargetDisplayProvider, rather than mocks.
859 TEST_F(WindowSizerAshTest, DefaultBoundsInTargetDisplay) {
860 if (!SupportsMultipleDisplays() || !chrome::ShouldOpenAshOnStartup())
861 return;
862 UpdateDisplay("500x500,600x600");
864 aura::Window* first_root =
865 ash::Shell::GetAllRootWindows()[0];
866 ash::ScopedTargetRootWindow tmp(first_root);
867 gfx::Rect bounds;
868 ui::WindowShowState show_state;
869 WindowSizer::GetBrowserWindowBoundsAndShowState(
870 std::string(),
871 gfx::Rect(),
872 NULL,
873 &bounds,
874 &show_state);
875 EXPECT_TRUE(first_root->GetBoundsInScreen().Contains(bounds));
878 aura::Window* second_root =
879 ash::Shell::GetAllRootWindows()[1];
880 ash::ScopedTargetRootWindow tmp(second_root);
881 gfx::Rect bounds;
882 ui::WindowShowState show_state;
883 WindowSizer::GetBrowserWindowBoundsAndShowState(
884 std::string(),
885 gfx::Rect(),
886 NULL,
887 &bounds,
888 &show_state);
889 EXPECT_TRUE(second_root->GetBoundsInScreen().Contains(bounds));
893 TEST_F(WindowSizerAshTest, TrustedPopupBehavior) {
894 scoped_ptr<TestingProfile> profile(new TestingProfile());
895 Browser::CreateParams trusted_popup_create_params(
896 Browser::TYPE_POPUP, profile.get(), chrome::HOST_DESKTOP_TYPE_ASH);
897 trusted_popup_create_params.trusted_source = true;
899 scoped_ptr<Browser> trusted_popup(CreateTestBrowser(
900 CreateTestWindowInShellWithId(1), gfx::Rect(16, 32, 640, 320),
901 &trusted_popup_create_params));
902 // Trusted popup windows should follow the saved show state and ignore the
903 // last show state.
904 EXPECT_EQ(
905 ui::SHOW_STATE_DEFAULT,
906 GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH,
907 trusted_popup.get(), p1280x1024, p1600x1200));
908 // A popup that is sized to occupy the whole work area has default state.
909 EXPECT_EQ(
910 ui::SHOW_STATE_DEFAULT,
911 GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH,
912 trusted_popup.get(), p1600x1200, p1600x1200));