1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <vector>
6
7#include "chrome/browser/ui/window_sizer.h"
8#include "base/logging.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11// Some standard monitor sizes (no task bar).
12static const gfx::Rect tentwentyfour(0, 0, 1024, 768);
13static const gfx::Rect twelveeighty(0, 0, 1280, 1024);
14static const gfx::Rect sixteenhundred(0, 0, 1600, 1200);
15static const gfx::Rect sixteeneighty(0, 0, 1680, 1050);
16static const gfx::Rect nineteentwenty(0, 0, 1920, 1200);
17
18// Represents a 1024x768 monitor that is not the primary monitor, arranged to
19// the immediate left of the primary 1024x768 monitor.
20static const gfx::Rect left_nonprimary(-1024, 0, 1024, 768);
21
22// Represents a 1024x768 monitor that is not the primary monitor, arranged to
23// the immediate right of the primary 1024x768 monitor.
24static const gfx::Rect right_nonprimary(1024, 0, 1024, 768);
25
26// Represents a 1024x768 monitor that is not the primary monitor, arranged to
27// the immediate top of the primary 1024x768 monitor.
28static const gfx::Rect top_nonprimary(0, -768, 1024, 768);
29
30// Represents a 1024x768 monitor that is not the primary monitor, arranged to
31// the immediate bottom of the primary 1024x768 monitor.
32static const gfx::Rect bottom_nonprimary(0, 768, 1024, 768);
33
34// The work area for 1024x768 monitors with different taskbar orientations.
35static const gfx::Rect taskbar_bottom_work_area(0, 0, 1024, 734);
36static const gfx::Rect taskbar_top_work_area(0, 34, 1024, 734);
37static const gfx::Rect taskbar_left_work_area(107, 0, 917, 768);
38static const gfx::Rect taskbar_right_work_area(0, 0, 917, 768);
39
40static int kWindowTilePixels = WindowSizer::kWindowTilePixels;
41
42// Testing implementation of WindowSizer::MonitorInfoProvider that we can use
43// to fake various monitor layouts and sizes.
44class TestMonitorInfoProvider : public WindowSizer::MonitorInfoProvider {
45 public:
46  TestMonitorInfoProvider() {}
47  virtual ~TestMonitorInfoProvider() {}
48
49  void AddMonitor(const gfx::Rect& bounds, const gfx::Rect& work_area) {
50    DCHECK(bounds.Contains(work_area));
51    monitor_bounds_.push_back(bounds);
52    work_areas_.push_back(work_area);
53  }
54
55  // Overridden from WindowSizer::MonitorInfoProvider:
56  virtual gfx::Rect GetPrimaryMonitorWorkArea() const {
57    return work_areas_[0];
58  }
59
60  virtual gfx::Rect GetPrimaryMonitorBounds() const {
61    return monitor_bounds_[0];
62  }
63
64  virtual gfx::Rect GetMonitorWorkAreaMatching(
65      const gfx::Rect& match_rect) const {
66    return work_areas_[GetMonitorIndexMatchingBounds(match_rect)];
67  }
68
69  virtual gfx::Point GetBoundsOffsetMatching(
70      const gfx::Rect& match_rect) const {
71    int monitor_index = GetMonitorIndexMatchingBounds(match_rect);
72    gfx::Rect bounds = monitor_bounds_[monitor_index];
73    const gfx::Rect& work_area = work_areas_[monitor_index];
74    return gfx::Point(work_area.x() - bounds.x(), work_area.y() - bounds.y());
75  }
76
77  virtual void UpdateWorkAreas() { }
78
79 private:
80  size_t GetMonitorIndexMatchingBounds(const gfx::Rect& match_rect) const {
81    int max_area = 0;
82    size_t max_area_index = 0;
83    // Loop through all the monitors, finding the one that intersects the
84    // largest area of the supplied match rect.
85    for (size_t i = 0; i < work_areas_.size(); ++i) {
86      gfx::Rect overlap(match_rect.Intersect(work_areas_[i]));
87      int area = overlap.width() * overlap.height();
88      if (area > max_area) {
89        max_area = area;
90        max_area_index = i;
91      }
92    }
93    return max_area_index;
94  }
95
96  std::vector<gfx::Rect> monitor_bounds_;
97
98  DISALLOW_COPY_AND_ASSIGN(TestMonitorInfoProvider);
99};
100
101// Testing implementation of WindowSizer::StateProvider that we use to fake
102// persistent storage and existing windows.
103class TestStateProvider : public WindowSizer::StateProvider {
104 public:
105  TestStateProvider()
106    : persistent_maximized_(false),
107      has_persistent_data_(false),
108      has_last_active_data_(false) {
109  }
110  virtual ~TestStateProvider() {}
111
112  void SetPersistentState(const gfx::Rect& bounds,
113                          bool maximized,
114                          const gfx::Rect& work_area,
115                          bool has_persistent_data) {
116    persistent_bounds_ = bounds;
117    persistent_maximized_ = maximized;
118    persistent_work_area_ = work_area;
119    has_persistent_data_ = has_persistent_data;
120  }
121
122  void SetLastActiveState(const gfx::Rect& bounds, bool has_last_active_data) {
123    last_active_bounds_ = bounds;
124    has_last_active_data_ = has_last_active_data;
125  }
126
127  // Overridden from WindowSizer::StateProvider:
128  virtual bool GetPersistentState(gfx::Rect* bounds,
129                                  bool* maximized,
130                                  gfx::Rect* saved_work_area) const {
131    *bounds = persistent_bounds_;
132    *maximized = persistent_maximized_;
133    *saved_work_area = persistent_work_area_;
134    return has_persistent_data_;
135  }
136
137  virtual bool GetLastActiveWindowState(gfx::Rect* bounds) const {
138    *bounds = last_active_bounds_;
139    return has_last_active_data_;
140  }
141
142 private:
143  gfx::Rect persistent_bounds_;
144  bool persistent_maximized_;
145  gfx::Rect persistent_work_area_;
146  bool has_persistent_data_;
147
148  gfx::Rect last_active_bounds_;
149  bool has_last_active_data_;
150
151  DISALLOW_COPY_AND_ASSIGN(TestStateProvider);
152};
153
154// A convenience function to read the window bounds from the window sizer
155// according to the specified configuration.
156enum Source { DEFAULT, LAST_ACTIVE, PERSISTED };
157static void GetWindowBounds(const gfx::Rect& monitor1_bounds,
158                            const gfx::Rect& monitor1_work_area,
159                            const gfx::Rect& monitor2_bounds,
160                            const gfx::Rect& state,
161                            bool maximized,
162                            const gfx::Rect& work_area,
163                            Source source,
164                            gfx::Rect* out_bounds,
165                            bool* out_maximized) {
166  TestMonitorInfoProvider* mip = new TestMonitorInfoProvider;
167  mip->AddMonitor(monitor1_bounds, monitor1_work_area);
168  if (!monitor2_bounds.IsEmpty())
169    mip->AddMonitor(monitor2_bounds, monitor2_bounds);
170  TestStateProvider* sp = new TestStateProvider;
171  if (source == PERSISTED)
172    sp->SetPersistentState(state, maximized, work_area, true);
173  else if (source == LAST_ACTIVE)
174    sp->SetLastActiveState(state, true);
175  WindowSizer sizer(sp, mip);
176  sizer.DetermineWindowBounds(gfx::Rect(), out_bounds, out_maximized);
177}
178
179// Test that the window is sized appropriately for the first run experience
180// where the default window bounds calculation is invoked.
181TEST(WindowSizerTest, DefaultSizeCase) {
182  { // 4:3 monitor case, 1024x768, no taskbar
183    gfx::Rect window_bounds;
184    bool maximized;
185    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), gfx::Rect(),
186                    false, gfx::Rect(), DEFAULT, &window_bounds, &maximized);
187    EXPECT_FALSE(maximized);
188    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
189                        1024 - kWindowTilePixels * 2,
190                        768 - kWindowTilePixels * 2),
191              window_bounds);
192  }
193
194  { // 4:3 monitor case, 1024x768, taskbar on bottom
195    gfx::Rect window_bounds;
196    bool maximized;
197    GetWindowBounds(tentwentyfour, taskbar_bottom_work_area, gfx::Rect(),
198                    gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds,
199                    &maximized);
200    EXPECT_FALSE(maximized);
201    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
202                        1024 - kWindowTilePixels * 2,
203                        (taskbar_bottom_work_area.height() -
204                         kWindowTilePixels * 2)),
205              window_bounds);
206  }
207
208  { // 4:3 monitor case, 1024x768, taskbar on right
209    gfx::Rect window_bounds;
210    bool maximized;
211    GetWindowBounds(tentwentyfour, taskbar_right_work_area, gfx::Rect(),
212                    gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds,
213                    &maximized);
214    EXPECT_FALSE(maximized);
215    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
216                        taskbar_right_work_area.width() - kWindowTilePixels*2,
217                        768 - kWindowTilePixels * 2),
218              window_bounds);
219  }
220
221  { // 4:3 monitor case, 1024x768, taskbar on left
222    gfx::Rect window_bounds;
223    bool maximized;
224    GetWindowBounds(tentwentyfour, taskbar_left_work_area, gfx::Rect(),
225                    gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds,
226                    &maximized);
227    EXPECT_FALSE(maximized);
228    EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kWindowTilePixels,
229                        kWindowTilePixels,
230                        taskbar_left_work_area.width() - kWindowTilePixels * 2,
231                        (taskbar_left_work_area.height() -
232                         kWindowTilePixels * 2)),
233              window_bounds);
234  }
235
236  { // 4:3 monitor case, 1024x768, taskbar on top
237    gfx::Rect window_bounds;
238    bool maximized;
239    GetWindowBounds(tentwentyfour, taskbar_top_work_area, gfx::Rect(),
240                    gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds,
241                    &maximized);
242    EXPECT_FALSE(maximized);
243    EXPECT_EQ(gfx::Rect(kWindowTilePixels,
244                        taskbar_top_work_area.y() + kWindowTilePixels,
245                        1024 - kWindowTilePixels * 2,
246                        taskbar_top_work_area.height() - kWindowTilePixels * 2),
247              window_bounds);
248  }
249
250  { // 4:3 monitor case, 1280x1024
251    gfx::Rect window_bounds;
252    bool maximized;
253    GetWindowBounds(twelveeighty, twelveeighty, gfx::Rect(), gfx::Rect(),
254                    false, gfx::Rect(), DEFAULT, &window_bounds, &maximized);
255    EXPECT_FALSE(maximized);
256    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
257                        1050,
258                        1024 - kWindowTilePixels * 2),
259              window_bounds);
260  }
261
262  { // 4:3 monitor case, 1600x1200
263    gfx::Rect window_bounds;
264    bool maximized;
265    GetWindowBounds(sixteenhundred, sixteenhundred, gfx::Rect(), gfx::Rect(),
266                    false, gfx::Rect(), DEFAULT, &window_bounds, &maximized);
267    EXPECT_FALSE(maximized);
268    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
269                        1050,
270                        1200 - kWindowTilePixels * 2),
271              window_bounds);
272  }
273
274  { // 16:10 monitor case, 1680x1050
275    gfx::Rect window_bounds;
276    bool maximized;
277    GetWindowBounds(sixteeneighty, sixteeneighty, gfx::Rect(), gfx::Rect(),
278                    false, gfx::Rect(), DEFAULT, &window_bounds, &maximized);
279    EXPECT_FALSE(maximized);
280    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
281                        840 - static_cast<int>(kWindowTilePixels * 1.5),
282                        1050 - kWindowTilePixels * 2),
283              window_bounds);
284  }
285
286  { // 16:10 monitor case, 1920x1200
287    gfx::Rect window_bounds;
288    bool maximized;
289    GetWindowBounds(nineteentwenty, nineteentwenty, gfx::Rect(), gfx::Rect(),
290                    false, gfx::Rect(), DEFAULT, &window_bounds, &maximized);
291    EXPECT_FALSE(maximized);
292    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
293                        960 - static_cast<int>(kWindowTilePixels * 1.5),
294                        1200 - kWindowTilePixels * 2),
295              window_bounds);
296  }
297}
298
299// Test that the next opened window is positioned appropriately given the
300// bounds of an existing window of the same type.
301TEST(WindowSizerTest, LastWindowBoundsCase) {
302  { // normal, in the middle of the screen somewhere.
303    gfx::Rect window_bounds;
304    bool maximized = false;
305    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
306                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400),
307                    false, gfx::Rect(), LAST_ACTIVE,
308                    &window_bounds, &maximized);
309    EXPECT_FALSE(maximized);
310    EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2,
311                        kWindowTilePixels * 2, 500, 400), window_bounds);
312  }
313
314  { // taskbar on top.
315    gfx::Rect window_bounds;
316    bool maximized = false;
317    GetWindowBounds(tentwentyfour, taskbar_top_work_area, gfx::Rect(),
318                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400),
319                    false, gfx::Rect(), LAST_ACTIVE,
320                    &window_bounds, &maximized);
321    EXPECT_FALSE(maximized);
322    EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2,
323                        std::max(kWindowTilePixels * 2,
324                                 34 /* toolbar height */),
325                        500, 400), window_bounds);
326  }
327
328  { // too small to satisify the minimum visibility condition.
329    gfx::Rect window_bounds;
330    bool maximized = false;
331    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
332                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29),
333                    false, gfx::Rect(), LAST_ACTIVE,
334                    &window_bounds, &maximized);
335    EXPECT_FALSE(maximized);
336    EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2,
337                        kWindowTilePixels * 2,
338                        30 /* not 29 */,
339                        30 /* not 29 */),
340              window_bounds);
341  }
342
343
344  { // normal, but maximized
345    gfx::Rect window_bounds;
346    bool maximized = false;
347    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
348                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400),
349                    true, gfx::Rect(), LAST_ACTIVE,
350                    &window_bounds, &maximized);
351    EXPECT_FALSE(maximized);
352    EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2,
353                        kWindowTilePixels * 2, 500, 400), window_bounds);
354  }
355}
356
357// Test that the window opened is sized appropriately given persisted sizes.
358TEST(WindowSizerTest, PersistedBoundsCase) {
359  { // normal, in the middle of the screen somewhere.
360    gfx::Rect initial_bounds(kWindowTilePixels, kWindowTilePixels, 500, 400);
361
362    gfx::Rect window_bounds;
363    bool maximized;
364    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), initial_bounds,
365                    false, gfx::Rect(), PERSISTED, &window_bounds, &maximized);
366    EXPECT_FALSE(maximized);
367    EXPECT_EQ(initial_bounds, window_bounds);
368  }
369
370  { // normal, maximized.
371    gfx::Rect initial_bounds(0, 0, 1024, 768);
372
373    gfx::Rect window_bounds;
374    bool maximized;
375    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), initial_bounds,
376                    true, gfx::Rect(), PERSISTED, &window_bounds, &maximized);
377    EXPECT_TRUE(maximized);
378    EXPECT_EQ(initial_bounds, window_bounds);
379  }
380
381  { // normal, on non-primary monitor in negative coords.
382    gfx::Rect initial_bounds(-600, 10, 500, 400);
383
384    gfx::Rect window_bounds;
385    bool maximized;
386    GetWindowBounds(tentwentyfour, tentwentyfour, left_nonprimary,
387                    initial_bounds, false, gfx::Rect(), PERSISTED,
388                    &window_bounds, &maximized);
389    EXPECT_FALSE(maximized);
390    EXPECT_EQ(initial_bounds, window_bounds);
391  }
392
393  { // normal, on non-primary monitor in negative coords, maximized.
394    gfx::Rect initial_bounds(-1024, 0, 1024, 768);
395
396    gfx::Rect window_bounds;
397    bool maximized;
398    GetWindowBounds(tentwentyfour, tentwentyfour, left_nonprimary,
399                    initial_bounds, true, gfx::Rect(), PERSISTED,
400                    &window_bounds, &maximized);
401    EXPECT_TRUE(maximized);
402    EXPECT_EQ(initial_bounds, window_bounds);
403  }
404
405  { // Non-primary monitor resoultion has changed, but the monitor still
406    // completely contains the window.
407
408    gfx::Rect initial_bounds(1074, 50, 600, 500);
409
410    gfx::Rect window_bounds;
411    bool maximized;
412    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(1024, 0, 800, 600),
413                    initial_bounds, false, right_nonprimary,
414                    PERSISTED, &window_bounds, &maximized);
415    EXPECT_FALSE(maximized);
416    EXPECT_EQ(initial_bounds, window_bounds);
417  }
418
419  { // Non-primary monitor resoultion has changed, and the window is partially
420    // off-screen.
421
422    gfx::Rect initial_bounds(1274, 50, 600, 500);
423
424    gfx::Rect window_bounds;
425    bool maximized;
426    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(1024, 0, 800, 600),
427                    initial_bounds, false, right_nonprimary,
428                    PERSISTED, &window_bounds, &maximized);
429    EXPECT_FALSE(maximized);
430    EXPECT_EQ(gfx::Rect(1224, 50, 600, 500), window_bounds);
431  }
432
433  { // Non-primary monitor resoultion has changed, and the window is now too
434    // large for the monitor.
435
436    gfx::Rect initial_bounds(1274, 50, 900, 700);
437
438    gfx::Rect window_bounds;
439    bool maximized;
440    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(1024, 0, 800, 600),
441                    initial_bounds, false, right_nonprimary,
442                    PERSISTED, &window_bounds, &maximized);
443    EXPECT_FALSE(maximized);
444    EXPECT_EQ(gfx::Rect(1024, 0, 800, 600), window_bounds);
445  }
446
447  { // width and height too small
448    gfx::Rect window_bounds;
449    bool maximized;
450    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
451                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29),
452                    false, gfx::Rect(), PERSISTED,
453                    &window_bounds, &maximized);
454    EXPECT_FALSE(maximized);
455    EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels,
456                        30 /* not 29 */, 30 /* not 29 */),
457              window_bounds);
458  }
459
460#if defined(OS_MACOSX)
461  { // Saved state is too tall to possibly be resized.  Mac resizers
462    // are at the bottom of the window, and no piece of a window can
463    // be moved higher than the menubar.  (Perhaps the user changed
464    // resolution to something smaller before relaunching Chrome?)
465    gfx::Rect window_bounds;
466    bool maximized;
467    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
468                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 30, 5000),
469                    false, gfx::Rect(), PERSISTED,
470                    &window_bounds, &maximized);
471    EXPECT_FALSE(maximized);
472    EXPECT_EQ(tentwentyfour.height(), window_bounds.height());
473  }
474#endif  // defined(OS_MACOSX)
475}
476
477//////////////////////////////////////////////////////////////////////////////
478// The following unittests have different results on Mac/non-Mac because we
479// reposition windows aggressively on Mac.  The *WithAggressiveReposition tests
480// are run on Mac, and the *WithNonAggressiveRepositioning tests are run on
481// other platforms.
482
483#if defined(OS_MACOSX)
484TEST(WindowSizerTest, LastWindowOffscreenWithAggressiveRepositioning) {
485  { // taskbar on left.  The new window overlaps slightly with the taskbar, so
486    // it is moved to be flush with the left edge of the work area.
487    gfx::Rect window_bounds;
488    bool maximized = false;
489    GetWindowBounds(tentwentyfour, taskbar_left_work_area, gfx::Rect(),
490                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400),
491                    false, gfx::Rect(), LAST_ACTIVE,
492                    &window_bounds, &maximized);
493    EXPECT_FALSE(maximized);
494    EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x(),
495                        kWindowTilePixels * 2, 500, 400), window_bounds);
496  }
497
498  { // offset would put the new window offscreen at the bottom
499    gfx::Rect window_bounds;
500    bool maximized = false;
501    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
502                    gfx::Rect(10, 729, 500, 400), false, gfx::Rect(),
503                    LAST_ACTIVE, &window_bounds, &maximized);
504    EXPECT_FALSE(maximized);
505    EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels,
506                        0 /* not 729 + kWindowTilePixels */,
507                        500, 400),
508              window_bounds);
509  }
510
511  { // offset would put the new window offscreen at the right
512    gfx::Rect window_bounds;
513    bool maximized = false;
514    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
515                    gfx::Rect(985, 10, 500, 400), false, gfx::Rect(),
516                    LAST_ACTIVE, &window_bounds, &maximized);
517    EXPECT_FALSE(maximized);
518    EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/,
519                        10 + kWindowTilePixels,
520                        500, 400),
521              window_bounds);
522  }
523
524  { // offset would put the new window offscreen at the bottom right
525    gfx::Rect window_bounds;
526    bool maximized = false;
527    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
528                    gfx::Rect(985, 729, 500, 400), false, gfx::Rect(),
529                    LAST_ACTIVE, &window_bounds, &maximized);
530    EXPECT_FALSE(maximized);
531    EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/,
532                        0 /* not 729 + kWindowTilePixels*/,
533                        500, 400),
534              window_bounds);
535  }
536}
537
538TEST(WindowSizerTest, PersistedWindowOffscreenWithAggressiveRepositioning) {
539  { // off the left
540    gfx::Rect window_bounds;
541    bool maximized;
542    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
543                    gfx::Rect(-471, 50, 500, 400), false, gfx::Rect(),
544                    PERSISTED, &window_bounds, &maximized);
545    EXPECT_FALSE(maximized);
546    EXPECT_EQ(gfx::Rect(0 /* not -471 */, 50, 500, 400), window_bounds);
547  }
548
549  { // off the top
550    gfx::Rect window_bounds;
551    bool maximized;
552    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
553                    gfx::Rect(50, -370, 500, 400), false, gfx::Rect(),
554                    PERSISTED, &window_bounds, &maximized);
555    EXPECT_FALSE(maximized);
556    EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds);
557  }
558
559  { // off the right
560    gfx::Rect window_bounds;
561    bool maximized;
562    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
563                    gfx::Rect(995, 50, 500, 400), false, gfx::Rect(),
564                    PERSISTED, &window_bounds, &maximized);
565    EXPECT_FALSE(maximized);
566    EXPECT_EQ(gfx::Rect(0 /* not 995 */, 50, 500, 400), window_bounds);
567  }
568
569  { // off the bottom
570    gfx::Rect window_bounds;
571    bool maximized;
572    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
573                    gfx::Rect(50, 739, 500, 400), false, gfx::Rect(), PERSISTED,
574                    &window_bounds, &maximized);
575    EXPECT_FALSE(maximized);
576    EXPECT_EQ(gfx::Rect(50, 0 /* not 739 */, 500, 400), window_bounds);
577  }
578
579  { // off the topleft
580    gfx::Rect window_bounds;
581    bool maximized;
582    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
583                    gfx::Rect(-471, -371, 500, 400), false, gfx::Rect(),
584                    PERSISTED, &window_bounds, &maximized);
585    EXPECT_FALSE(maximized);
586    EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not -371 */, 500, 400),
587              window_bounds);
588  }
589
590  { // off the topright
591    gfx::Rect window_bounds;
592    bool maximized;
593    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
594                    gfx::Rect(995, -371, 500, 400), false, gfx::Rect(),
595                    PERSISTED, &window_bounds, &maximized);
596    EXPECT_FALSE(maximized);
597    EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not -371 */, 500, 400),
598                        window_bounds);
599  }
600
601  { // off the bottomleft
602    gfx::Rect window_bounds;
603    bool maximized;
604    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
605                    gfx::Rect(-471, 739, 500, 400), false, gfx::Rect(),
606                    PERSISTED, &window_bounds, &maximized);
607    EXPECT_FALSE(maximized);
608    EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not 739 */, 500, 400),
609                        window_bounds);
610  }
611
612  { // off the bottomright
613    gfx::Rect window_bounds;
614    bool maximized;
615    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
616                    gfx::Rect(995, 739, 500, 400), false, gfx::Rect(),
617                    PERSISTED, &window_bounds, &maximized);
618    EXPECT_FALSE(maximized);
619    EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not 739 */, 500, 400),
620                        window_bounds);
621  }
622
623  { // entirely off left
624    gfx::Rect window_bounds;
625    bool maximized;
626    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
627                    gfx::Rect(-700, 50, 500, 400), false, gfx::Rect(),
628                    PERSISTED, &window_bounds, &maximized);
629    EXPECT_FALSE(maximized);
630    EXPECT_EQ(gfx::Rect(0 /* not -700 */, 50, 500, 400), window_bounds);
631  }
632
633  { // entirely off left (monitor was detached since last run)
634    gfx::Rect window_bounds;
635    bool maximized;
636    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
637                    gfx::Rect(-700, 50, 500, 400), false, left_nonprimary,
638                    PERSISTED, &window_bounds, &maximized);
639    EXPECT_FALSE(maximized);
640    EXPECT_EQ(gfx::Rect(0, 50, 500, 400), window_bounds);
641  }
642
643  { // entirely off top
644    gfx::Rect window_bounds;
645    bool maximized;
646    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
647                    gfx::Rect(50, -500, 500, 400), false, gfx::Rect(),
648                    PERSISTED, &window_bounds, &maximized);
649    EXPECT_FALSE(maximized);
650    EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds);
651  }
652
653  { // entirely off top (monitor was detached since last run)
654    gfx::Rect window_bounds;
655    bool maximized;
656    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
657                    gfx::Rect(50, -500, 500, 400), false, top_nonprimary,
658                    PERSISTED, &window_bounds, &maximized);
659    EXPECT_FALSE(maximized);
660    EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds);
661  }
662
663  { // entirely off right
664    gfx::Rect window_bounds;
665    bool maximized;
666    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
667                    gfx::Rect(1200, 50, 500, 400), false, gfx::Rect(),
668                    PERSISTED, &window_bounds, &maximized);
669    EXPECT_FALSE(maximized);
670    EXPECT_EQ(gfx::Rect(0 /* not 1200 */, 50, 500, 400), window_bounds);
671  }
672
673  { // entirely off right (monitor was detached since last run)
674    gfx::Rect window_bounds;
675    bool maximized;
676    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
677                    gfx::Rect(1200, 50, 500, 400), false, right_nonprimary,
678                    PERSISTED, &window_bounds, &maximized);
679    EXPECT_FALSE(maximized);
680    EXPECT_EQ(gfx::Rect(524 /* not 1200 */, 50, 500, 400), window_bounds);
681  }
682
683  { // entirely off bottom
684    gfx::Rect window_bounds;
685    bool maximized;
686    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
687                    gfx::Rect(50, 800, 500, 400), false, gfx::Rect(), PERSISTED,
688                    &window_bounds, &maximized);
689    EXPECT_FALSE(maximized);
690    EXPECT_EQ(gfx::Rect(50, 0 /* not 800 */, 500, 400), window_bounds);
691  }
692
693  { // entirely off bottom (monitor was detached since last run)
694    gfx::Rect window_bounds;
695    bool maximized;
696    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
697                    gfx::Rect(50, 800, 500, 400), false, bottom_nonprimary,
698                    PERSISTED, &window_bounds, &maximized);
699    EXPECT_FALSE(maximized);
700    EXPECT_EQ(gfx::Rect(50, 368 /* not 800 */, 500, 400), window_bounds);
701  }
702
703  { // wider than the screen. off both the left and right
704    gfx::Rect window_bounds;
705    bool maximized;
706    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
707                    gfx::Rect(-100, 50, 2000, 400), false, gfx::Rect(),
708                    PERSISTED, &window_bounds, &maximized);
709    EXPECT_FALSE(maximized);
710    EXPECT_EQ(gfx::Rect(0 /* not -100 */, 50, 2000, 400), window_bounds);
711  }
712}
713#else
714TEST(WindowSizerTest, LastWindowOffscreenWithNonAggressiveRepositioning) {
715  { // taskbar on left.
716    gfx::Rect window_bounds;
717    bool maximized = false;
718    GetWindowBounds(tentwentyfour, taskbar_left_work_area, gfx::Rect(),
719                    gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400),
720                    false, gfx::Rect(), LAST_ACTIVE,
721                    &window_bounds, &maximized);
722    EXPECT_FALSE(maximized);
723    EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2,
724                        kWindowTilePixels * 2, 500, 400), window_bounds);
725  }
726
727  // Linux does not tile windows, so tile adjustment tests don't make sense.
728#if !defined(OS_LINUX)
729  { // offset would put the new window offscreen at the bottom but the minimum
730    // visibility condition is barely satisfied without relocation.
731    gfx::Rect window_bounds;
732    bool maximized = false;
733    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
734                    gfx::Rect(10, 728, 500, 400), false, gfx::Rect(),
735                    LAST_ACTIVE, &window_bounds, &maximized);
736    EXPECT_FALSE(maximized);
737    EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738,
738                        500, 400), window_bounds);
739  }
740
741  { // offset would put the new window offscreen at the bottom and the minimum
742    // visibility condition is satisified by relocation.
743    gfx::Rect window_bounds;
744    bool maximized = false;
745    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
746                    gfx::Rect(10, 729, 500, 400), false, gfx::Rect(),
747                    LAST_ACTIVE, &window_bounds, &maximized);
748    EXPECT_FALSE(maximized);
749    EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738 /* not 739 */, 500, 400),
750              window_bounds);
751  }
752
753  { // offset would put the new window offscreen at the right but the minimum
754    // visibility condition is barely satisfied without relocation.
755    gfx::Rect window_bounds;
756    bool maximized = false;
757    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
758                    gfx::Rect(984, 10, 500, 400), false, gfx::Rect(),
759                    LAST_ACTIVE, &window_bounds, &maximized);
760    EXPECT_FALSE(maximized);
761    EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400), window_bounds);
762  }
763
764  { // offset would put the new window offscreen at the right and the minimum
765    // visibility condition is satisified by relocation.
766    gfx::Rect window_bounds;
767    bool maximized = false;
768    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
769                    gfx::Rect(985, 10, 500, 400), false, gfx::Rect(),
770                    LAST_ACTIVE, &window_bounds, &maximized);
771    EXPECT_FALSE(maximized);
772    EXPECT_EQ(gfx::Rect(994 /* not 995 */, 10 + kWindowTilePixels,
773                        500, 400), window_bounds);
774  }
775
776  { // offset would put the new window offscreen at the bottom right and the
777    // minimum visibility condition is satisified by relocation.
778    gfx::Rect window_bounds;
779    bool maximized = false;
780    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
781                    gfx::Rect(985, 729, 500, 400), false, gfx::Rect(),
782                    LAST_ACTIVE, &window_bounds, &maximized);
783    EXPECT_FALSE(maximized);
784    EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400),
785              window_bounds);
786  }
787#endif  // !defined(OS_LINUX)
788}
789
790TEST(WindowSizerTest, PersistedWindowOffscreenWithNonAggressiveRepositioning) {
791  { // off the left but the minimum visibility condition is barely satisfied
792    // without relocaiton.
793    gfx::Rect initial_bounds(-470, 50, 500, 400);
794
795    gfx::Rect window_bounds;
796    bool maximized;
797    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
798                    initial_bounds, false, gfx::Rect(), PERSISTED,
799                    &window_bounds, &maximized);
800    EXPECT_FALSE(maximized);
801    EXPECT_EQ(initial_bounds, window_bounds);
802  }
803
804  { // off the left and the minimum visibility condition is satisfied by
805    // relocation.
806    gfx::Rect window_bounds;
807    bool maximized;
808    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
809                    gfx::Rect(-471, 50, 500, 400), false, gfx::Rect(),
810                    PERSISTED, &window_bounds, &maximized);
811    EXPECT_FALSE(maximized);
812    EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 50, 500, 400), window_bounds);
813  }
814
815  { // off the top
816    gfx::Rect initial_bounds(50, -370, 500, 400);
817
818    gfx::Rect window_bounds;
819    bool maximized;
820    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
821                    gfx::Rect(50, -370, 500, 400), false, gfx::Rect(),
822                    PERSISTED, &window_bounds, &maximized);
823    EXPECT_FALSE(maximized);
824    EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds);
825  }
826
827  { // off the right but the minimum visibility condition is barely satisified
828    // without relocation.
829    gfx::Rect initial_bounds(994, 50, 500, 400);
830
831    gfx::Rect window_bounds;
832    bool maximized;
833    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
834                    initial_bounds, false, gfx::Rect(), PERSISTED,
835                    &window_bounds, &maximized);
836    EXPECT_FALSE(maximized);
837    EXPECT_EQ(initial_bounds, window_bounds);
838  }
839
840  { // off the right and the minimum visibility condition is satisified by
841    // relocation.
842    gfx::Rect window_bounds;
843    bool maximized;
844    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
845                    gfx::Rect(995, 50, 500, 400), false, gfx::Rect(),
846                    PERSISTED, &window_bounds, &maximized);
847    EXPECT_FALSE(maximized);
848    EXPECT_EQ(gfx::Rect(994 /* not 995 */, 50, 500, 400), window_bounds);
849  }
850
851  { // off the bottom but the minimum visibility condition is barely satisified
852    // without relocation.
853    gfx::Rect initial_bounds(50, 738, 500, 400);
854
855    gfx::Rect window_bounds;
856    bool maximized;
857    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
858                    initial_bounds, false, gfx::Rect(), PERSISTED,
859                    &window_bounds, &maximized);
860    EXPECT_FALSE(maximized);
861    EXPECT_EQ(initial_bounds, window_bounds);
862  }
863
864  { // off the bottom and the minimum visibility condition is satisified by
865    // relocation.
866    gfx::Rect window_bounds;
867    bool maximized;
868    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
869                    gfx::Rect(50, 739, 500, 400), false, gfx::Rect(), PERSISTED,
870                    &window_bounds, &maximized);
871    EXPECT_FALSE(maximized);
872    EXPECT_EQ(gfx::Rect(50, 738 /* not 739 */, 500, 400), window_bounds);
873  }
874
875  { // off the topleft
876    gfx::Rect window_bounds;
877    bool maximized;
878    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
879                    gfx::Rect(-471, -371, 500, 400), false, gfx::Rect(),
880                    PERSISTED, &window_bounds, &maximized);
881    EXPECT_FALSE(maximized);
882    EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 0, 500, 400),
883              window_bounds);
884  }
885
886  { // off the topright and the minimum visibility condition is satisified by
887    // relocation.
888    gfx::Rect window_bounds;
889    bool maximized;
890    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
891                    gfx::Rect(995, -371, 500, 400), false, gfx::Rect(),
892                    PERSISTED, &window_bounds, &maximized);
893    EXPECT_FALSE(maximized);
894    EXPECT_EQ(gfx::Rect(994 /* not 995 */, 0, 500, 400),
895                        window_bounds);
896  }
897
898  { // off the bottomleft and the minimum visibility condition is satisified by
899    // relocation.
900    gfx::Rect window_bounds;
901    bool maximized;
902    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
903                    gfx::Rect(-471, 739, 500, 400), false, gfx::Rect(),
904                    PERSISTED, &window_bounds, &maximized);
905    EXPECT_FALSE(maximized);
906    EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 738 /* not 739 */, 500, 400),
907                        window_bounds);
908  }
909
910  { // off the bottomright and the minimum visibility condition is satisified by
911    // relocation.
912    gfx::Rect window_bounds;
913    bool maximized;
914    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
915                    gfx::Rect(995, 739, 500, 400), false, gfx::Rect(),
916                    PERSISTED, &window_bounds, &maximized);
917    EXPECT_FALSE(maximized);
918    EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400),
919                        window_bounds);
920  }
921
922  { // entirely off left
923    gfx::Rect window_bounds;
924    bool maximized;
925    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
926                    gfx::Rect(-700, 50, 500, 400), false, gfx::Rect(),
927                    PERSISTED, &window_bounds, &maximized);
928    EXPECT_FALSE(maximized);
929    EXPECT_EQ(gfx::Rect(-470 /* not -700 */, 50, 500, 400), window_bounds);
930  }
931
932  { // entirely off left (monitor was detached since last run)
933    gfx::Rect window_bounds;
934    bool maximized;
935    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
936                    gfx::Rect(-700, 50, 500, 400), false, left_nonprimary,
937                    PERSISTED, &window_bounds, &maximized);
938    EXPECT_FALSE(maximized);
939    EXPECT_EQ(gfx::Rect(0, 50, 500, 400), window_bounds);
940  }
941
942  { // entirely off top
943    gfx::Rect window_bounds;
944    bool maximized;
945    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
946                    gfx::Rect(50, -500, 500, 400), false, gfx::Rect(),
947                    PERSISTED, &window_bounds, &maximized);
948    EXPECT_FALSE(maximized);
949    EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds);
950  }
951
952  { // entirely off top (monitor was detached since last run)
953    gfx::Rect window_bounds;
954    bool maximized;
955    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
956                    gfx::Rect(50, -500, 500, 400), false, top_nonprimary,
957                    PERSISTED, &window_bounds, &maximized);
958    EXPECT_FALSE(maximized);
959    EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds);
960  }
961
962  { // entirely off right
963    gfx::Rect window_bounds;
964    bool maximized;
965    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
966                    gfx::Rect(1200, 50, 500, 400), false, gfx::Rect(),
967                    PERSISTED, &window_bounds, &maximized);
968    EXPECT_FALSE(maximized);
969    EXPECT_EQ(gfx::Rect(994 /* not 1200 */, 50, 500, 400), window_bounds);
970  }
971
972  { // entirely off right (monitor was detached since last run)
973    gfx::Rect window_bounds;
974    bool maximized;
975    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
976                    gfx::Rect(1200, 50, 500, 400), false, right_nonprimary,
977                    PERSISTED, &window_bounds, &maximized);
978    EXPECT_FALSE(maximized);
979    EXPECT_EQ(gfx::Rect(524, 50, 500, 400), window_bounds);
980  }
981
982  { // entirely off bottom
983    gfx::Rect window_bounds;
984    bool maximized;
985    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
986                    gfx::Rect(50, 800, 500, 400), false, gfx::Rect(), PERSISTED,
987                    &window_bounds, &maximized);
988    EXPECT_FALSE(maximized);
989    EXPECT_EQ(gfx::Rect(50, 738 /* not 800 */, 500, 400), window_bounds);
990  }
991
992  { // entirely off bottom (monitor was detached since last run)
993    gfx::Rect window_bounds;
994    bool maximized;
995    GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(),
996                    gfx::Rect(50, 800, 500, 400), false, bottom_nonprimary,
997                    PERSISTED, &window_bounds, &maximized);
998    EXPECT_FALSE(maximized);
999    EXPECT_EQ(gfx::Rect(50, 368, 500, 400), window_bounds);
1000  }
1001}
1002#endif  //defined(OS_MACOSX)
1003