OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 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 "chrome/browser/window_sizer.h" | |
6 | |
7 #include "chrome/browser/browser_list.h" | |
8 #include "chrome/browser/browser_window.h" | |
9 #include "chrome/browser/ui/browser.h" | |
10 | |
11 // How much horizontal and vertical offset there is between newly | |
12 // opened windows. | |
13 const int WindowSizer::kWindowTilePixels = 10; | |
14 | |
15 // An implementation of WindowSizer::MonitorInfoProvider that gets the actual | |
16 // monitor information from Windows. | |
17 class DefaultMonitorInfoProvider : public WindowSizer::MonitorInfoProvider { | |
18 public: | |
19 DefaultMonitorInfoProvider() { } | |
20 | |
21 // Overridden from WindowSizer::MonitorInfoProvider: | |
22 virtual gfx::Rect GetPrimaryMonitorWorkArea() const { | |
23 return gfx::Rect(GetMonitorInfoForMonitor(MonitorFromWindow(NULL, | |
24 MONITOR_DEFAULTTOPRIMARY)).rcWork); | |
25 } | |
26 | |
27 virtual gfx::Rect GetPrimaryMonitorBounds() const { | |
28 return gfx::Rect(GetMonitorInfoForMonitor(MonitorFromWindow(NULL, | |
29 MONITOR_DEFAULTTOPRIMARY)).rcMonitor); | |
30 } | |
31 | |
32 virtual gfx::Rect GetMonitorWorkAreaMatching( | |
33 const gfx::Rect& match_rect) const { | |
34 RECT other_bounds_rect = match_rect.ToRECT(); | |
35 MONITORINFO monitor_info = GetMonitorInfoForMonitor(MonitorFromRect( | |
36 &other_bounds_rect, MONITOR_DEFAULTTONEAREST)); | |
37 return gfx::Rect(monitor_info.rcWork); | |
38 } | |
39 | |
40 virtual gfx::Point GetBoundsOffsetMatching( | |
41 const gfx::Rect& match_rect) const { | |
42 RECT other_bounds_rect = match_rect.ToRECT(); | |
43 MONITORINFO monitor_info = GetMonitorInfoForMonitor(MonitorFromRect( | |
44 &other_bounds_rect, MONITOR_DEFAULTTONEAREST)); | |
45 return gfx::Point(monitor_info.rcWork.left - monitor_info.rcMonitor.left, | |
46 monitor_info.rcWork.top - monitor_info.rcMonitor.top); | |
47 } | |
48 | |
49 void UpdateWorkAreas() { | |
50 work_areas_.clear(); | |
51 EnumDisplayMonitors(NULL, NULL, | |
52 &DefaultMonitorInfoProvider::MonitorEnumProc, | |
53 reinterpret_cast<LPARAM>(&work_areas_)); | |
54 } | |
55 | |
56 private: | |
57 // A callback for EnumDisplayMonitors that records the work area of the | |
58 // current monitor in the enumeration. | |
59 static BOOL CALLBACK MonitorEnumProc(HMONITOR monitor, | |
60 HDC monitor_dc, | |
61 LPRECT monitor_rect, | |
62 LPARAM data) { | |
63 reinterpret_cast<std::vector<gfx::Rect>*>(data)->push_back( | |
64 gfx::Rect(GetMonitorInfoForMonitor(monitor).rcWork)); | |
65 return TRUE; | |
66 } | |
67 | |
68 static MONITORINFO GetMonitorInfoForMonitor(HMONITOR monitor) { | |
69 MONITORINFO monitor_info = { 0 }; | |
70 monitor_info.cbSize = sizeof(monitor_info); | |
71 GetMonitorInfo(monitor, &monitor_info); | |
72 return monitor_info; | |
73 } | |
74 | |
75 DISALLOW_COPY_AND_ASSIGN(DefaultMonitorInfoProvider); | |
76 }; | |
77 | |
78 // static | |
79 WindowSizer::MonitorInfoProvider* | |
80 WindowSizer::CreateDefaultMonitorInfoProvider() { | |
81 return new DefaultMonitorInfoProvider(); | |
82 } | |
83 | |
84 // static | |
85 gfx::Point WindowSizer::GetDefaultPopupOrigin(const gfx::Size& size) { | |
86 RECT area; | |
87 SystemParametersInfo(SPI_GETWORKAREA, 0, &area, 0); | |
88 gfx::Point corner(area.left, area.top); | |
89 | |
90 if (Browser* b = BrowserList::GetLastActive()) { | |
91 RECT browser; | |
92 HWND window = reinterpret_cast<HWND>(b->window()->GetNativeHandle()); | |
93 if (GetWindowRect(window, &browser)) { | |
94 // Limit to not overflow the work area right and bottom edges. | |
95 gfx::Point limit( | |
96 std::min(browser.left + kWindowTilePixels, area.right-size.width()), | |
97 std::min(browser.top + kWindowTilePixels, area.bottom-size.height()) | |
98 ); | |
99 // Adjust corner to now overflow the work area left and top edges, so | |
100 // that if a popup does not fit the title-bar is remains visible. | |
101 corner = gfx::Point( | |
102 std::max(corner.x(), limit.x()), | |
103 std::max(corner.y(), limit.y()) | |
104 ); | |
105 } | |
106 } | |
107 return corner; | |
108 } | |
OLD | NEW |