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/screen_ash.h"
7 #include "ash/test/ash_test_base.h"
8 #include "ash/test/test_shell_delegate.h"
9 #include "ash/wm/window_positioner.h"
10 #include "ash/wm/window_resizer.h"
11 #include "ash/wm/window_state.h"
12 #include "base/compiler_specific.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/window_sizer/window_sizer_common_unittest.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/test/render_view_test.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/aura/client/activation_client.h"
20 #include "ui/aura/client/aura_constants.h"
21 #include "ui/aura/env.h"
22 #include "ui/aura/root_window.h"
23 #include "ui/aura/test/test_windows.h"
25 typedef ash::test::AshTestBase WindowSizerAshTest;
29 // A browser window proxy which is able to associate an aura native window with
31 class TestBrowserWindowAura : public TestBrowserWindow {
33 // |native_window| will still be owned by the caller after the constructor
35 explicit TestBrowserWindowAura(aura::Window* native_window)
36 : native_window_(native_window) {
38 virtual ~TestBrowserWindowAura() {}
40 // TestBrowserWindow overrides:
41 virtual void Show() OVERRIDE {
42 native_window_->Show();
45 virtual void Hide() OVERRIDE {
46 native_window_->Hide();
48 virtual void Activate() OVERRIDE {
49 aura::client::GetActivationClient(
50 native_window_->GetRootWindow())->ActivateWindow(native_window_.get());
52 virtual gfx::NativeWindow GetNativeWindow() OVERRIDE {
53 return native_window_.get();
55 virtual gfx::Rect GetBounds() const OVERRIDE {
56 return native_window_->bounds();
59 Browser* browser() { return browser_.get(); }
61 void CreateBrowser(const Browser::CreateParams& params) {
62 Browser::CreateParams create_params = params;
63 create_params.window = this;
64 browser_.reset(new Browser(create_params));
65 if (browser_->is_type_tabbed() || browser_->is_app()) {
66 ash::wm::GetWindowState(native_window_.get())->
67 set_window_position_managed(true);
72 scoped_ptr<Browser> browser_;
73 scoped_ptr<aura::Window> native_window_;
75 DISALLOW_COPY_AND_ASSIGN(TestBrowserWindowAura);
78 scoped_ptr<TestBrowserWindowAura> CreateTestBrowserWindow(
80 const gfx::Rect& bounds,
81 const Browser::CreateParams& params) {
82 if (!bounds.IsEmpty())
83 window->SetBounds(bounds);
84 scoped_ptr<TestBrowserWindowAura> browser_window(
85 new TestBrowserWindowAura(window));
86 browser_window->CreateBrowser(params);
87 return browser_window.Pass();
92 // Test that the window is sized appropriately for the first run experience
93 // where the default window bounds calculation is invoked.
94 TEST_F(WindowSizerAshTest, DefaultSizeCase) {
95 { // 4:3 monitor case, 1024x768, no taskbar
96 gfx::Rect window_bounds;
97 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(),
98 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
99 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
100 ash::WindowPositioner::kDesktopBorderSize,
101 1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
102 768 - ash::WindowPositioner::kDesktopBorderSize),
106 { // 4:3 monitor case, 1024x768, taskbar on bottom
107 gfx::Rect window_bounds;
108 GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(),
109 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
111 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
112 ash::WindowPositioner::kDesktopBorderSize,
113 1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
114 taskbar_bottom_work_area.height() -
115 ash::WindowPositioner::kDesktopBorderSize),
119 { // 4:3 monitor case, 1024x768, taskbar on right
120 gfx::Rect window_bounds;
121 GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(),
122 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
124 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
125 ash::WindowPositioner::kDesktopBorderSize,
126 taskbar_right_work_area.width() -
127 ash::WindowPositioner::kDesktopBorderSize * 2,
128 768 - ash::WindowPositioner::kDesktopBorderSize),
132 { // 4:3 monitor case, 1024x768, taskbar on left
133 gfx::Rect window_bounds;
134 GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(),
135 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
137 EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() +
138 ash::WindowPositioner::kDesktopBorderSize,
139 ash::WindowPositioner::kDesktopBorderSize,
140 taskbar_left_work_area.width() -
141 ash::WindowPositioner::kDesktopBorderSize * 2,
142 taskbar_left_work_area.height() -
143 ash::WindowPositioner::kDesktopBorderSize),
147 { // 4:3 monitor case, 1024x768, taskbar on top
148 gfx::Rect window_bounds;
149 GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(),
150 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
152 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
153 taskbar_top_work_area.y() +
154 ash::WindowPositioner::kDesktopBorderSize,
155 1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
156 taskbar_top_work_area.height() -
157 ash::WindowPositioner::kDesktopBorderSize),
161 { // 4:3 monitor case, 1280x1024
162 gfx::Rect window_bounds;
163 GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(),
164 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
165 EXPECT_EQ(gfx::Rect((1280 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
166 ash::WindowPositioner::kDesktopBorderSize,
167 ash::WindowPositioner::kMaximumWindowWidth,
168 1024 - ash::WindowPositioner::kDesktopBorderSize),
172 { // 4:3 monitor case, 1600x1200
173 gfx::Rect window_bounds;
174 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(),
175 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
176 EXPECT_EQ(gfx::Rect((1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
177 ash::WindowPositioner::kDesktopBorderSize,
178 ash::WindowPositioner::kMaximumWindowWidth,
179 1200 - ash::WindowPositioner::kDesktopBorderSize),
183 { // 16:10 monitor case, 1680x1050
184 gfx::Rect window_bounds;
185 GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(),
186 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
187 EXPECT_EQ(gfx::Rect((1680 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
188 ash::WindowPositioner::kDesktopBorderSize,
189 ash::WindowPositioner::kMaximumWindowWidth,
190 1050 - ash::WindowPositioner::kDesktopBorderSize),
194 { // 16:10 monitor case, 1920x1200
195 gfx::Rect window_bounds;
196 GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(),
197 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
198 EXPECT_EQ(gfx::Rect((1920 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
199 ash::WindowPositioner::kDesktopBorderSize,
200 ash::WindowPositioner::kMaximumWindowWidth,
201 1200 - ash::WindowPositioner::kDesktopBorderSize),
206 // Test that the next opened window is positioned appropriately given the
207 // bounds of an existing window of the same type.
208 TEST_F(WindowSizerAshTest, LastWindowBoundsCase) {
209 { // normal, in the middle of the screen somewhere.
210 gfx::Rect window_bounds;
212 p1024x768, p1024x768, gfx::Rect(),
213 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
214 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
215 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
218 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
219 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
220 500, 400).ToString(),
221 window_bounds.ToString());
225 gfx::Rect window_bounds;
227 p1024x768, taskbar_top_work_area, gfx::Rect(),
228 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
229 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
230 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
233 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
234 std::max(kWindowTilePixels +
235 ash::WindowPositioner::kDesktopBorderSize,
236 34 /* toolbar height */),
237 500, 400).ToString(),
238 window_bounds.ToString());
241 { // Too small to satisify the minimum visibility condition.
242 gfx::Rect window_bounds;
244 p1024x768, p1024x768, gfx::Rect(),
245 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
246 ash::WindowPositioner::kDesktopBorderSize, 29, 29),
247 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
250 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
251 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
253 30 /* not 29 */).ToString(),
254 window_bounds.ToString());
259 gfx::Rect window_bounds;
261 p1024x768, p1024x768, gfx::Rect(),
262 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
263 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
264 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
267 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
268 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
269 500, 400).ToString(),
270 window_bounds.ToString());
274 // Test that the window opened is sized appropriately given persisted sizes.
275 TEST_F(WindowSizerAshTest, PersistedBoundsCase) {
276 { // normal, in the middle of the screen somewhere.
277 gfx::Rect initial_bounds(
278 ash::WindowPositioner::kDesktopBorderSize,
279 ash::WindowPositioner::kDesktopBorderSize, 500, 400);
281 gfx::Rect window_bounds;
282 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
283 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
284 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
288 gfx::Rect initial_bounds(0, 0, 1024, 768);
290 gfx::Rect window_bounds;
291 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
292 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
293 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
296 { // normal, on non-primary monitor in negative coords.
297 gfx::Rect initial_bounds(-600, 10, 500, 400);
299 gfx::Rect window_bounds;
300 GetWindowBounds(p1024x768, p1024x768, left_s1024x768,
301 initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(),
303 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
306 { // normal, on non-primary monitor in negative coords.
307 gfx::Rect initial_bounds(-1024, 0, 1024, 768);
309 gfx::Rect window_bounds;
310 GetWindowBounds(p1024x768, p1024x768, left_s1024x768,
311 initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(),
313 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
316 { // Non-primary monitor resoultion has changed, but the monitor still
317 // completely contains the window.
319 gfx::Rect initial_bounds(1074, 50, 600, 500);
321 gfx::Rect window_bounds;
322 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
323 initial_bounds, right_s1024x768, PERSISTED, NULL,
324 gfx::Rect(), &window_bounds);
325 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
328 { // Non-primary monitor resoultion has changed, and the window is partially
331 gfx::Rect initial_bounds(1274, 50, 600, 500);
333 gfx::Rect window_bounds;
334 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
335 initial_bounds, right_s1024x768, PERSISTED,
336 NULL, gfx::Rect(), &window_bounds);
337 EXPECT_EQ("1224,50 600x500", window_bounds.ToString());
340 { // Non-primary monitor resoultion has changed, and the window is now too
341 // large for the monitor.
343 gfx::Rect initial_bounds(1274, 50, 900, 700);
345 gfx::Rect window_bounds;
346 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
347 initial_bounds, right_s1024x768, PERSISTED,
348 NULL, gfx::Rect(), &window_bounds);
349 EXPECT_EQ("1024,0 800x600", window_bounds.ToString());
352 { // width and height too small
353 gfx::Rect window_bounds;
355 p1024x768, p1024x768, gfx::Rect(),
356 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
357 ash::WindowPositioner::kDesktopBorderSize, 29, 29),
358 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
359 EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
360 ash::WindowPositioner::kDesktopBorderSize,
361 30 /* not 29 */, 30 /* not 29 */).ToString(),
362 window_bounds.ToString());
366 //////////////////////////////////////////////////////////////////////////////
367 // The following unittests have different results on Mac/non-Mac because we
368 // reposition windows aggressively on Mac. The *WithAggressiveReposition tests
369 // are run on Mac, and the *WithNonAggressiveRepositioning tests are run on
372 TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) {
373 { // taskbar on left.
374 gfx::Rect window_bounds;
376 p1024x768, taskbar_left_work_area, gfx::Rect(),
377 gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
378 ash::WindowPositioner::kDesktopBorderSize, 500, 400),
379 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
382 gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
383 kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
384 500, 400).ToString(),
385 window_bounds.ToString());
388 { // offset would put the new window offscreen at the bottom but the minimum
389 // visibility condition is barely satisfied without relocation.
390 gfx::Rect window_bounds;
391 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
392 gfx::Rect(10, 728, 500, 400), gfx::Rect(), LAST_ACTIVE,
393 NULL, gfx::Rect(), &window_bounds);
394 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400).ToString(),
395 window_bounds.ToString());
398 { // offset would put the new window offscreen at the bottom and the minimum
399 // visibility condition is satisified by relocation.
400 gfx::Rect window_bounds;
401 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
402 gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE,
403 NULL, gfx::Rect(), &window_bounds);
404 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels,
408 window_bounds.ToString());
411 { // offset would put the new window offscreen at the right but the minimum
412 // visibility condition is barely satisfied without relocation.
413 gfx::Rect window_bounds;
414 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
415 gfx::Rect(984, 10, 500, 400), gfx::Rect(), LAST_ACTIVE,
416 NULL, gfx::Rect(), &window_bounds);
417 EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400).ToString(),
418 window_bounds.ToString());
421 { // offset would put the new window offscreen at the right and the minimum
422 // visibility condition is satisified by relocation.
423 gfx::Rect window_bounds;
424 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
425 gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE,
426 NULL, gfx::Rect(), &window_bounds);
427 EXPECT_EQ(gfx::Rect(994 /* not 995 */,
428 10 + kWindowTilePixels,
431 window_bounds.ToString());
434 { // offset would put the new window offscreen at the bottom right and the
435 // minimum visibility condition is satisified by relocation.
436 gfx::Rect window_bounds;
437 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
438 gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE,
439 NULL, gfx::Rect(), &window_bounds);
440 EXPECT_EQ(gfx::Rect(994 /* not 995 */,
444 window_bounds.ToString());
448 // Test the placement of newly created windows.
449 TEST_F(WindowSizerAshTest, PlaceNewWindows) {
450 // Create a browser which we can use to pass into the GetWindowBounds
452 scoped_ptr<TestingProfile> profile(new TestingProfile());
453 // Creating a popup handler here to make sure it does not interfere with the
455 Browser::CreateParams native_params(profile.get(),
456 chrome::HOST_DESKTOP_TYPE_ASH);
457 scoped_ptr<Browser> browser(
458 chrome::CreateBrowserWithTestWindowForParams(&native_params));
460 // Creating a popup handler here to make sure it does not interfere with the
462 scoped_ptr<BrowserWindow> browser_window(CreateTestBrowserWindow(
463 CreateTestWindowInShellWithId(0),
464 gfx::Rect(16, 32, 640, 320),
465 Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH)));
467 // Creating a popup to make sure it does not interfere with the positioning.
468 scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow(
469 CreateTestWindowInShellWithId(1),
470 gfx::Rect(16, 32, 128, 256),
471 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
472 chrome::HOST_DESKTOP_TYPE_ASH)));
474 // Creating a panel to make sure it does not interfere with the positioning.
475 scoped_ptr<BrowserWindow> browser_panel(CreateTestBrowserWindow(
476 CreateTestWindowInShellWithId(2),
477 gfx::Rect(32, 48, 256, 512),
478 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
479 chrome::HOST_DESKTOP_TYPE_ASH)));
480 browser_window->Show();
481 { // Make sure that popups do not get changed.
482 gfx::Rect window_bounds;
483 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
484 gfx::Rect(50, 100, 300, 150), bottom_s1600x1200,
485 PERSISTED, browser_popup->browser(),
486 gfx::Rect(), &window_bounds);
487 EXPECT_EQ("50,100 300x150", window_bounds.ToString());
490 browser_window->Hide();
491 { // If a window is there but not shown the persisted default should be used.
492 gfx::Rect window_bounds;
493 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
494 gfx::Rect(50, 100, 300, 150), bottom_s1600x1200,
495 PERSISTED, browser.get(), gfx::Rect(), &window_bounds);
496 EXPECT_EQ("50,100 300x150", window_bounds.ToString());
499 { // If a window is there but not shown the default should be returned.
500 gfx::Rect window_bounds;
501 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
502 gfx::Rect(), bottom_s1600x1200,
503 DEFAULT, browser.get(), gfx::Rect(), &window_bounds);
504 // Note: We need to also take the defaults maximum width into account here
505 // since that might get used if the resolution is too big.
508 std::max(ash::WindowPositioner::kDesktopBorderSize,
509 (1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2),
510 ash::WindowPositioner::kDesktopBorderSize,
511 std::min(ash::WindowPositioner::kMaximumWindowWidth,
512 1600 - 2 * ash::WindowPositioner::kDesktopBorderSize),
513 1200 - ash::WindowPositioner::kDesktopBorderSize).ToString(),
514 window_bounds.ToString());
518 // Test the placement of newly created windows on an empty desktop.
519 // This test supplements "PlaceNewWindows" by testing the creation of a newly
520 // created browser window on an empty desktop.
521 TEST_F(WindowSizerAshTest, PlaceNewBrowserWindowOnEmptyDesktop) {
522 // Create a browser which we can use to pass into the GetWindowBounds
524 scoped_ptr<TestingProfile> profile(new TestingProfile());
525 Browser::CreateParams native_params(profile.get(),
526 chrome::HOST_DESKTOP_TYPE_ASH);
527 scoped_ptr<Browser> browser(
528 chrome::CreateBrowserWithTestWindowForParams(&native_params));
530 // A common screen size for Chrome OS devices where this behavior is
532 const gfx::Rect p1366x768(0, 0, 1366, 768);
534 // If there is no previous state the window should get maximized if the
535 // screen is less than or equal to our limit (1366 pixels width).
536 gfx::Rect window_bounds;
537 ui::WindowShowState out_show_state1 = 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(), // 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 DEFAULT, // No persisted values.
547 browser.get(), // Use this browser.
548 gfx::Rect(), // Don't request valid bounds.
551 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, out_show_state1);
553 // If there is a stored coordinate however, that should be taken instead.
554 ui::WindowShowState out_show_state2 = ui::SHOW_STATE_DEFAULT;
555 GetWindowBoundsAndShowState(
556 p1366x768, // The screen resolution.
557 p1366x768, // The monitor work area.
558 gfx::Rect(), // The second monitor.
559 gfx::Rect(50, 100, 300, 150), // The (persisted) bounds.
560 p1366x768, // The overall work area.
561 ui::SHOW_STATE_NORMAL, // The persisted show state.
562 ui::SHOW_STATE_DEFAULT, // The last show state.
563 PERSISTED, // Set the persisted values.
564 browser.get(), // Use this browser.
565 gfx::Rect(), // Don't request valid bounds.
568 EXPECT_EQ(ui::SHOW_STATE_NORMAL, out_show_state2);
569 EXPECT_EQ("50,100 300x150", window_bounds.ToString());
571 // A larger monitor should not trigger auto-maximize.
572 ui::WindowShowState out_show_state3 = ui::SHOW_STATE_DEFAULT;
573 GetWindowBoundsAndShowState(
574 p1600x1200, // The screen resolution.
575 p1600x1200, // The monitor work area.
576 gfx::Rect(), // The second monitor.
577 gfx::Rect(), // The (persisted) bounds.
578 p1600x1200, // The overall work area.
579 ui::SHOW_STATE_NORMAL, // The persisted show state.
580 ui::SHOW_STATE_DEFAULT, // The last show state.
581 DEFAULT, // No persisted values.
582 browser.get(), // Use this browser.
583 gfx::Rect(), // Don't request valid bounds.
586 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, out_show_state3);
589 #if defined(OS_CHROMEOS)
590 #define MAYBE_PlaceNewWindowsOnMultipleDisplays PlaceNewWindowsOnMultipleDisplays
592 // No multiple displays on windows ash.
593 #define MAYBE_PlaceNewWindowsOnMultipleDisplays DISABLED_PlaceNewWindowsOnMultipleDisplays
596 // Test the placement of newly created windows on multiple dislays.
597 TEST_F(WindowSizerAshTest, MAYBE_PlaceNewWindowsOnMultipleDisplays) {
598 UpdateDisplay("1600x1200,1600x1200");
599 gfx::Rect primary_bounds = ash::Shell::GetInstance()->GetScreen()->
600 GetPrimaryDisplay().bounds();
601 gfx::Rect secondary_bounds = ash::ScreenAsh::GetSecondaryDisplay().bounds();
603 ash::Shell::GetInstance()->set_target_root_window(
604 ash::Shell::GetPrimaryRootWindow());
606 scoped_ptr<TestingProfile> profile(new TestingProfile());
608 // Create browser windows that are used as reference.
609 scoped_ptr<BrowserWindow> browser_window(CreateTestBrowserWindow(
610 CreateTestWindowInShellWithId(0),
611 gfx::Rect(10, 10, 200, 200),
612 Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH)));
613 browser_window->Show();
614 EXPECT_EQ(browser_window->GetNativeWindow()->GetRootWindow(),
615 ash::Shell::GetTargetRootWindow());
617 scoped_ptr<BrowserWindow> another_browser_window(CreateTestBrowserWindow(
618 CreateTestWindowInShellWithId(1),
619 gfx::Rect(400, 10, 300, 300),
620 Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH)));
621 another_browser_window->Show();
623 // Creating a new window to verify the new placement.
624 scoped_ptr<TestBrowserWindowAura> new_browser_window(CreateTestBrowserWindow(
625 CreateTestWindowInShellWithId(0),
627 Browser::CreateParams(profile.get(),
628 chrome::HOST_DESKTOP_TYPE_ASH)));
630 // Make sure the primary root is active.
631 ASSERT_EQ(ash::Shell::GetPrimaryRootWindow(),
632 ash::Shell::GetTargetRootWindow());
634 // First new window should be in the primary.
636 gfx::Rect window_bounds;
637 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds,
638 gfx::Rect(), secondary_bounds,
639 PERSISTED, new_browser_window->browser(),
640 gfx::Rect(), &window_bounds);
641 // TODO(oshima): Use exact bounds when the window_sizer_ash is
642 // moved to ash and changed to include the result from
643 // RearrangeVisibleWindowOnShow.
644 EXPECT_TRUE(primary_bounds.Contains(window_bounds));
647 // Move the window to the right side of the secondary display and create a new
648 // window. It should be opened then on the secondary display.
650 gfx::Display second_display = ash::Shell::GetScreen()->
651 GetDisplayNearestPoint(gfx::Point(1600 + 100,10));
652 browser_window->GetNativeWindow()->SetBoundsInScreen(
653 gfx::Rect(secondary_bounds.CenterPoint().x() - 100, 10, 200, 200),
655 browser_window->Activate();
656 EXPECT_NE(ash::Shell::GetPrimaryRootWindow(),
657 ash::Shell::GetTargetRootWindow());
658 gfx::Rect window_bounds;
659 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds,
660 gfx::Rect(), secondary_bounds,
661 PERSISTED, new_browser_window->browser(),
662 gfx::Rect(), &window_bounds);
663 // TODO(oshima): Use exact bounds when the window_sizer_ash is
664 // moved to ash and changed to include the result from
665 // RearrangeVisibleWindowOnShow.
666 EXPECT_TRUE(secondary_bounds.Contains(window_bounds));
669 // Activate another window in the primary display and create a new window.
670 // It should be created in the primary display.
672 another_browser_window->Activate();
673 EXPECT_EQ(ash::Shell::GetPrimaryRootWindow(),
674 ash::Shell::GetTargetRootWindow());
676 gfx::Rect window_bounds;
677 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds,
678 gfx::Rect(), secondary_bounds,
679 PERSISTED, new_browser_window->browser(),
680 gfx::Rect(), &window_bounds);
681 // TODO(oshima): Use exact bounds when the window_sizer_ash is
682 // moved to ash and changed to include the result from
683 // RearrangeVisibleWindowOnShow.
684 EXPECT_TRUE(primary_bounds.Contains(window_bounds));
688 // Test that the show state is properly returned for non default cases.
689 TEST_F(WindowSizerAshTest, TestShowState) {
690 scoped_ptr<TestingProfile> profile(new TestingProfile());
692 // Creating a browser & window to play with.
693 scoped_ptr<TestBrowserWindowAura> browser_window(CreateTestBrowserWindow(
694 CreateTestWindowInShellWithId(0),
695 gfx::Rect(16, 32, 640, 320),
696 Browser::CreateParams(Browser::TYPE_TABBED, profile.get(),
697 chrome::HOST_DESKTOP_TYPE_ASH)));
699 // Create also a popup browser since that behaves different.
700 scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow(
701 CreateTestWindowInShellWithId(1),
702 gfx::Rect(16, 32, 640, 320),
703 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
704 chrome::HOST_DESKTOP_TYPE_ASH)));
706 // Tabbed windows should retrieve the saved window state - since there is a
708 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
709 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
710 ui::SHOW_STATE_NORMAL,
712 browser_window->browser(),
714 EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
715 GetWindowShowState(ui::SHOW_STATE_DEFAULT,
716 ui::SHOW_STATE_NORMAL,
718 browser_window->browser(),
720 // Non tabbed windows should always follow the window saved visibility state.
721 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
722 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
723 ui::SHOW_STATE_NORMAL,
725 browser_popup->browser(),
727 // The non tabbed window will take the status of the last active of its kind.
728 EXPECT_EQ(ui::SHOW_STATE_NORMAL,
729 GetWindowShowState(ui::SHOW_STATE_DEFAULT,
730 ui::SHOW_STATE_NORMAL,
732 browser_popup->browser(),
735 // Now create a top level window and check again for both. Only the tabbed
736 // window should follow the top level window's state.
737 // Creating a browser & window to play with.
738 scoped_ptr<TestBrowserWindowAura> browser_window2(CreateTestBrowserWindow(
739 CreateTestWindowInShellWithId(3),
740 gfx::Rect(16, 32, 640, 320),
741 Browser::CreateParams(Browser::TYPE_TABBED, profile.get(),
742 chrome::HOST_DESKTOP_TYPE_ASH)));
744 // A tabbed window should now take the top level window state.
745 EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
746 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
747 ui::SHOW_STATE_DEFAULT,
749 browser_window->browser(),
751 // Non tabbed windows should always follow the window saved visibility state.
752 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
753 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
754 ui::SHOW_STATE_MINIMIZED,
756 browser_popup->browser(),
759 // In smaller screen resolutions we default to maximized if there is no other
761 int min_size = ash::WindowPositioner::GetForceMaximizedWidthLimit() / 2;
763 const gfx::Rect tiny_screen(0, 0, min_size, min_size);
764 EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
765 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
766 ui::SHOW_STATE_DEFAULT,
768 browser_window->browser(),
770 browser_window->Hide();
771 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
772 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
773 ui::SHOW_STATE_DEFAULT,
775 browser_window2->browser(),
781 // Test that the default show state override behavior is properly handled.
782 TEST_F(WindowSizerAshTest, TestShowStateDefaults) {
783 // Creating a browser & window to play with.
784 scoped_ptr<TestingProfile> profile(new TestingProfile());
786 scoped_ptr<TestBrowserWindowAura> browser_window(CreateTestBrowserWindow(
787 CreateTestWindowInShellWithId(0),
788 gfx::Rect(16, 32, 640, 320),
789 Browser::CreateParams(Browser::TYPE_TABBED, profile.get(),
790 chrome::HOST_DESKTOP_TYPE_ASH)));
792 // Create also a popup browser since that behaves slightly different for
794 scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow(
795 CreateTestWindowInShellWithId(1),
796 gfx::Rect(16, 32, 128, 256),
797 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
798 chrome::HOST_DESKTOP_TYPE_ASH)));
800 // Check that a browser creation state always get used if not given as
801 // SHOW_STATE_DEFAULT.
802 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
803 ui::SHOW_STATE_MAXIMIZED,
805 browser_window->browser(),
806 p1600x1200), ui::SHOW_STATE_DEFAULT);
807 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_MINIMIZED);
808 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
809 ui::SHOW_STATE_MAXIMIZED,
811 browser_window->browser(),
812 p1600x1200), ui::SHOW_STATE_MINIMIZED);
813 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_NORMAL);
814 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
815 ui::SHOW_STATE_MAXIMIZED,
817 browser_window->browser(),
818 p1600x1200), ui::SHOW_STATE_NORMAL);
819 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_MAXIMIZED);
820 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL,
821 ui::SHOW_STATE_NORMAL,
823 browser_window->browser(),
824 p1600x1200), ui::SHOW_STATE_MAXIMIZED);
826 // Check that setting the maximized command line option is forcing the
828 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kStartMaximized);
830 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_NORMAL);
831 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL,
832 ui::SHOW_STATE_NORMAL,
834 browser_window->browser(),
835 p1600x1200), ui::SHOW_STATE_MAXIMIZED);
837 // The popup should favor the initial show state over the command line.
838 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL,
839 ui::SHOW_STATE_NORMAL,
841 browser_popup->browser(),
842 p1600x1200), ui::SHOW_STATE_NORMAL);