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"
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
;
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
),
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();
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
55 #define MAYBE_DefaultSizeCase DefaultSizeCase
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
) {
62 base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kOpenAsh
);
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
),
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(),
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
),
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(),
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
),
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(),
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
),
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(),
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
),
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
),
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
),
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
),
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
),
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
;
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(),
187 gfx::Rect(kWindowTilePixels
+ ash::WindowPositioner::kDesktopBorderSize
,
188 kWindowTilePixels
+ ash::WindowPositioner::kDesktopBorderSize
,
189 500, 400).ToString(),
190 window_bounds
.ToString());
194 gfx::Rect window_bounds
;
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(),
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
;
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(),
219 gfx::Rect(kWindowTilePixels
+ ash::WindowPositioner::kDesktopBorderSize
,
220 kWindowTilePixels
+ ash::WindowPositioner::kDesktopBorderSize
,
222 30 /* not 29 */).ToString(),
223 window_bounds
.ToString());
228 gfx::Rect window_bounds
;
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(),
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());
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(),
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(),
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
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
;
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
341 TEST_F(WindowSizerAshTest
, LastWindowOffscreenWithNonAggressiveRepositioning
) {
342 { // taskbar on left.
343 gfx::Rect window_bounds
;
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(),
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
,
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
,
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 */,
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
422 #define MAYBE_PlaceNewWindows PlaceNewWindows
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
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
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), ¶ms2
));
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), ¶ms_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), ¶ms_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.
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
499 #define MAYBE_PlaceNewBrowserWindowOnEmptyDesktop PlaceNewBrowserWindowOnEmptyDesktop
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
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.
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.
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.
570 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED
, out_show_state3
);
572 EXPECT_EQ(ui::SHOW_STATE_DEFAULT
, out_show_state3
);
576 #if defined(OS_CHROMEOS)
577 #define MAYBE_PlaceNewWindowsOnMultipleDisplays PlaceNewWindowsOnMultipleDisplays
579 // No multiple displays on windows ash.
580 #define MAYBE_PlaceNewWindowsOnMultipleDisplays DISABLED_PlaceNewWindowsOnMultipleDisplays
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), ¶ms
));
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(),
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),
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(),
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(),
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
682 #define MAYBE_TestShowState TestShowState
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), ¶ms
));
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), ¶ms_popup
));
702 // Tabbed windows should retrieve the saved window state - since there is a
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.
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.
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), ¶ms2
));
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.
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
746 int min_size
= ash::WindowPositioner::GetForceMaximizedWidthLimit() / 2;
748 const gfx::Rect
tiny_screen(0, 0, min_size
, min_size
);
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();
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), ¶ms
));
771 // Create also a popup browser since that behaves slightly different for
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), ¶ms_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
);
785 EXPECT_EQ(window_show_state
, ui::SHOW_STATE_MAXIMIZED
);
787 EXPECT_EQ(window_show_state
, ui::SHOW_STATE_DEFAULT
);
790 browser
->set_initial_show_state(ui::SHOW_STATE_MINIMIZED
);
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
);
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
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.
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
;
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())
862 UpdateDisplay("500x500,600x600");
864 aura::Window
* first_root
=
865 ash::Shell::GetAllRootWindows()[0];
866 ash::ScopedTargetRootWindow
tmp(first_root
);
868 ui::WindowShowState show_state
;
869 WindowSizer::GetBrowserWindowBoundsAndShowState(
875 EXPECT_TRUE(first_root
->GetBoundsInScreen().Contains(bounds
));
878 aura::Window
* second_root
=
879 ash::Shell::GetAllRootWindows()[1];
880 ash::ScopedTargetRootWindow
tmp(second_root
);
882 ui::WindowShowState show_state
;
883 WindowSizer::GetBrowserWindowBoundsAndShowState(
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
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.
910 ui::SHOW_STATE_DEFAULT
,
911 GetWindowShowState(ui::SHOW_STATE_DEFAULT
, ui::SHOW_STATE_NORMAL
, BOTH
,
912 trusted_popup
.get(), p1600x1200
, p1600x1200
));