blob: bb4148fbf3b26572056c7f2c8002ad9ab4dfa1b0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/window_sizer.h"
#include "ash/shell.h"
#include "ash/wm/window_cycle_controller.h"
#include "ash/wm/window_util.h"
#include "base/compiler_specific.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/gfx/screen.h"
namespace {
// Check if the window was not created as popup or as panel.
bool IsValidToplevelWindow(aura::Window* window) {
for (BrowserList::const_iterator iter = BrowserList::begin();
iter != BrowserList::end();
++iter) {
Browser* browser = *iter;
if (browser && browser->window() &&
browser->window()->GetNativeHandle() == window) {
return (!(browser->is_type_popup() || browser->is_type_panel()));
}
}
// A window which has no browser associated with it is probably not a window
// of which we want to copy the size from.
return false;
}
// Get the first open window in the stack on the screen.
aura::Window* GetTopWindow() {
// Get the active window.
aura::Window* window = ash::wm::GetActiveWindow();
if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL &&
window->IsVisible() && IsValidToplevelWindow(window))
return window;
// Get a list of all windows.
const std::vector<aura::Window*> windows =
ash::WindowCycleController::BuildWindowList();
if (windows.empty())
return NULL;
aura::Window::Windows::const_iterator iter = windows.begin();
// Find the index of the current window.
if (window)
iter = std::find(windows.begin(), windows.end(), window);
int index = (iter == windows.end()) ? 0 : (iter - windows.begin());
// Scan the cycle list backwards to see which is the second topmost window
// (and so on). Note that we might cycle a few indices twice if there is no
// suitable window. However - since the list is fairly small this should be
// very fast anyways.
for (int i = index + windows.size(); i >= 0; i--) {
aura::Window* window = windows[i % windows.size()];
if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL &&
window->IsVisible() && IsValidToplevelWindow(window))
return window;
}
return NULL;
}
} // namespace
bool WindowSizer::GetBoundsIgnoringPreviousState(
const gfx::Rect& specified_bounds,
gfx::Rect* bounds) const {
*bounds = specified_bounds;
DCHECK(bounds->IsEmpty());
if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) {
// This is a window / app. See if there is no window and try to place it.
aura::Window* top_window = GetTopWindow();
// If there are no windows we have a special case and try to
// maximize which leaves a 'border' which shows the desktop.
if (top_window == NULL) {
GetDefaultWindowBounds(bounds);
} else {
*bounds = top_window->GetBoundsInRootWindow();
}
return true;
// If both fail we will continue the default path.
}
return false;
}
void WindowSizer::GetDefaultWindowBounds(gfx::Rect* default_bounds) const {
DCHECK(default_bounds);
DCHECK(monitor_info_provider_.get());
gfx::Rect work_area = monitor_info_provider_->GetPrimaryMonitorWorkArea();
DCHECK_EQ(kDesktopBorderSize, ash::Shell::GetInstance()->GetGridSize());
// There should be a 'desktop' border around the window at the left and right
// side.
int default_width = work_area.width() - 2 * kDesktopBorderSize;
// There should also be a 'desktop' border around the window at the top.
// Since the workspace excludes the tray area we only need one border size.
int default_height = work_area.height() - kDesktopBorderSize;
// We align the size to the grid size to avoid any surprise when the
// monitor height isn't divide-able by our alignment factor.
default_width -= default_width % kDesktopBorderSize;
default_height -= default_height % kDesktopBorderSize;
int offset_x = kDesktopBorderSize;
int maximum_window_width = 1280;
if (default_width > maximum_window_width) {
// The window should get centered on the screen and not follow the grid.
offset_x = (work_area.width() - maximum_window_width) / 2;
// Never make a window wider then 1280.
default_width = maximum_window_width;
}
default_bounds->SetRect(work_area.x() + offset_x,
work_area.y() + kDesktopBorderSize,
default_width,
default_height);
}
|