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
|
// Copyright (c) 2009 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 "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
// How much horizontal and vertical offset there is between newly
// opened windows.
const int WindowSizer::kWindowTilePixels = 10;
// An implementation of WindowSizer::MonitorInfoProvider that gets the actual
// monitor information from Windows.
class DefaultMonitorInfoProvider : public WindowSizer::MonitorInfoProvider {
public:
DefaultMonitorInfoProvider() { }
// Overridden from WindowSizer::MonitorInfoProvider:
virtual gfx::Rect GetPrimaryMonitorWorkArea() const {
return gfx::Rect(GetMonitorInfoForMonitor(MonitorFromWindow(NULL,
MONITOR_DEFAULTTOPRIMARY)).rcWork);
}
virtual gfx::Rect GetPrimaryMonitorBounds() const {
return gfx::Rect(GetMonitorInfoForMonitor(MonitorFromWindow(NULL,
MONITOR_DEFAULTTOPRIMARY)).rcMonitor);
}
virtual gfx::Rect GetMonitorWorkAreaMatching(
const gfx::Rect& match_rect) const {
RECT other_bounds_rect = match_rect.ToRECT();
MONITORINFO monitor_info = GetMonitorInfoForMonitor(MonitorFromRect(
&other_bounds_rect, MONITOR_DEFAULTTONEAREST));
return gfx::Rect(monitor_info.rcWork);
}
virtual gfx::Point GetBoundsOffsetMatching(
const gfx::Rect& match_rect) const {
RECT other_bounds_rect = match_rect.ToRECT();
MONITORINFO monitor_info = GetMonitorInfoForMonitor(MonitorFromRect(
&other_bounds_rect, MONITOR_DEFAULTTONEAREST));
return gfx::Point(monitor_info.rcWork.left - monitor_info.rcMonitor.left,
monitor_info.rcWork.top - monitor_info.rcMonitor.top);
}
void UpdateWorkAreas() {
work_areas_.clear();
EnumDisplayMonitors(NULL, NULL,
&DefaultMonitorInfoProvider::MonitorEnumProc,
reinterpret_cast<LPARAM>(&work_areas_));
}
private:
// A callback for EnumDisplayMonitors that records the work area of the
// current monitor in the enumeration.
static BOOL CALLBACK MonitorEnumProc(HMONITOR monitor,
HDC monitor_dc,
LPRECT monitor_rect,
LPARAM data) {
reinterpret_cast<std::vector<gfx::Rect>*>(data)->push_back(
gfx::Rect(GetMonitorInfoForMonitor(monitor).rcWork));
return TRUE;
}
static MONITORINFO GetMonitorInfoForMonitor(HMONITOR monitor) {
MONITORINFO monitor_info = { 0 };
monitor_info.cbSize = sizeof(monitor_info);
GetMonitorInfo(monitor, &monitor_info);
return monitor_info;
}
DISALLOW_COPY_AND_ASSIGN(DefaultMonitorInfoProvider);
};
// static
WindowSizer::MonitorInfoProvider*
WindowSizer::CreateDefaultMonitorInfoProvider() {
return new DefaultMonitorInfoProvider();
}
// static
gfx::Point WindowSizer::GetDefaultPopupOrigin(const gfx::Size& size) {
RECT area;
SystemParametersInfo(SPI_GETWORKAREA, 0, &area, 0);
gfx::Point corner(area.left, area.top);
if (Browser* b = BrowserList::GetLastActive()) {
RECT browser;
HWND window = reinterpret_cast<HWND>(b->window()->GetNativeHandle());
if (GetWindowRect(window, &browser)) {
// Limit to not overflow the work area right and bottom edges.
gfx::Point limit(
std::min(browser.left + kWindowTilePixels, area.right-size.width()),
std::min(browser.top + kWindowTilePixels, area.bottom-size.height())
);
// Adjust corner to now overflow the work area left and top edges, so
// that if a popup does not fit the title-bar is remains visible.
corner = gfx::Point(
std::max(corner.x(), limit.x()),
std::max(corner.y(), limit.y())
);
}
}
return corner;
}
|