Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(608)

Side by Side Diff: chrome/browser/dock_info_win.cc

Issue 5544002: Move a bunch more browser stuff around.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/dock_info_unittest.cc ('k') | chrome/browser/encoding_menu_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/dock_info.h"
6
7 #include "base/basictypes.h"
8 #include "chrome/browser/browser_list.h"
9 #include "chrome/browser/browser_window.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/views/frame/browser_view.h"
12 #include "chrome/browser/views/tabs/tab.h"
13
14 namespace {
15
16 // BaseWindowFinder -----------------------------------------------------------
17
18 // Base class used to locate a window. This is intended to be used with the
19 // various win32 functions that iterate over windows.
20 //
21 // A subclass need only override ShouldStopIterating to determine when
22 // iteration should stop.
23 class BaseWindowFinder {
24 public:
25 // Creates a BaseWindowFinder with the specified set of HWNDs to ignore.
26 explicit BaseWindowFinder(const std::set<HWND>& ignore) : ignore_(ignore) {}
27 virtual ~BaseWindowFinder() {}
28
29 protected:
30 // Returns true if iteration should stop, false if iteration should continue.
31 virtual bool ShouldStopIterating(HWND window) = 0;
32
33 static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
34 BaseWindowFinder* finder = reinterpret_cast<BaseWindowFinder*>(lParam);
35 if (finder->ignore_.find(hwnd) != finder->ignore_.end())
36 return TRUE;
37
38 return finder->ShouldStopIterating(hwnd) ? FALSE : TRUE;
39 }
40
41 private:
42 const std::set<HWND>& ignore_;
43
44 DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
45 };
46
47 // TopMostFinder --------------------------------------------------------------
48
49 // Helper class to determine if a particular point of a window is not obscured
50 // by another window.
51 class TopMostFinder : public BaseWindowFinder {
52 public:
53 // Returns true if |window| is the topmost window at the location
54 // |screen_loc|, not including the windows in |ignore|.
55 static bool IsTopMostWindowAtPoint(HWND window,
56 const gfx::Point& screen_loc,
57 const std::set<HWND>& ignore) {
58 TopMostFinder finder(window, screen_loc, ignore);
59 return finder.is_top_most_;
60 }
61
62 virtual bool ShouldStopIterating(HWND hwnd) {
63 if (hwnd == target_) {
64 // Window is topmost, stop iterating.
65 is_top_most_ = true;
66 return true;
67 }
68
69 if (!IsWindowVisible(hwnd)) {
70 // The window isn't visible, keep iterating.
71 return false;
72 }
73
74 RECT r;
75 if (!GetWindowRect(hwnd, &r) || !PtInRect(&r, screen_loc_.ToPOINT())) {
76 // The window doesn't contain the point, keep iterating.
77 return false;
78 }
79
80 LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE);
81 if (ex_styles & WS_EX_TRANSPARENT || ex_styles & WS_EX_LAYERED) {
82 // Mouse events fall through WS_EX_TRANSPARENT windows, so we ignore them.
83 //
84 // WS_EX_LAYERED is trickier. Apps like Switcher create a totally
85 // transparent WS_EX_LAYERED window that is always on top. If we don't
86 // ignore WS_EX_LAYERED windows and there are totally transparent
87 // WS_EX_LAYERED windows then there are effectively holes on the screen
88 // that the user can't reattach tabs to. So we ignore them. This is a bit
89 // problematic in so far as WS_EX_LAYERED windows need not be totally
90 // transparent in which case we treat chrome windows as not being obscured
91 // when they really are, but this is better than not being able to
92 // reattach tabs.
93 return false;
94 }
95
96 // hwnd is at the point. Make sure the point is within the windows region.
97 if (GetWindowRgn(hwnd, tmp_region_.Get()) == ERROR) {
98 // There's no region on the window and the window contains the point. Stop
99 // iterating.
100 return true;
101 }
102
103 // The region is relative to the window's rect.
104 BOOL is_point_in_region = PtInRegion(tmp_region_.Get(),
105 screen_loc_.x() - r.left, screen_loc_.y() - r.top);
106 tmp_region_ = CreateRectRgn(0, 0, 0, 0);
107 // Stop iterating if the region contains the point.
108 return !!is_point_in_region;
109 }
110
111 private:
112 TopMostFinder(HWND window,
113 const gfx::Point& screen_loc,
114 const std::set<HWND>& ignore)
115 : BaseWindowFinder(ignore),
116 target_(window),
117 screen_loc_(screen_loc),
118 is_top_most_(false),
119 tmp_region_(CreateRectRgn(0, 0, 0, 0)) {
120 EnumWindows(WindowCallbackProc, reinterpret_cast<LPARAM>(this));
121 }
122
123 // The window we're looking for.
124 HWND target_;
125
126 // Location of window to find.
127 gfx::Point screen_loc_;
128
129 // Is target_ the top most window? This is initially false but set to true
130 // in ShouldStopIterating if target_ is passed in.
131 bool is_top_most_;
132
133 ScopedRegion tmp_region_;
134
135 DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
136 };
137
138 // WindowFinder ---------------------------------------------------------------
139
140 // Helper class to determine if a particular point contains a window from our
141 // process.
142 class LocalProcessWindowFinder : public BaseWindowFinder {
143 public:
144 // Returns the hwnd from our process at screen_loc that is not obscured by
145 // another window. Returns NULL otherwise.
146 static HWND GetProcessWindowAtPoint(const gfx::Point& screen_loc,
147 const std::set<HWND>& ignore) {
148 LocalProcessWindowFinder finder(screen_loc, ignore);
149 if (finder.result_ &&
150 TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
151 ignore)) {
152 return finder.result_;
153 }
154 return NULL;
155 }
156
157 protected:
158 virtual bool ShouldStopIterating(HWND hwnd) {
159 RECT r;
160 if (IsWindowVisible(hwnd) && GetWindowRect(hwnd, &r) &&
161 PtInRect(&r, screen_loc_.ToPOINT())) {
162 result_ = hwnd;
163 return true;
164 }
165 return false;
166 }
167
168 private:
169 LocalProcessWindowFinder(const gfx::Point& screen_loc,
170 const std::set<HWND>& ignore)
171 : BaseWindowFinder(ignore),
172 screen_loc_(screen_loc),
173 result_(NULL) {
174 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
175 reinterpret_cast<LPARAM>(this));
176 }
177
178 // Position of the mouse.
179 gfx::Point screen_loc_;
180
181 // The resulting window. This is initially null but set to true in
182 // ShouldStopIterating if an appropriate window is found.
183 HWND result_;
184
185 DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
186 };
187
188 // DockToWindowFinder ---------------------------------------------------------
189
190 // Helper class for creating a DockInfo from a specified point.
191 class DockToWindowFinder : public BaseWindowFinder {
192 public:
193 // Returns the DockInfo for the specified point. If there is no docking
194 // position for the specified point the returned DockInfo has a type of NONE.
195 static DockInfo GetDockInfoAtPoint(const gfx::Point& screen_loc,
196 const std::set<HWND>& ignore) {
197 DockToWindowFinder finder(screen_loc, ignore);
198 if (!finder.result_.window() ||
199 !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.window(),
200 finder.result_.hot_spot(),
201 ignore)) {
202 finder.result_.set_type(DockInfo::NONE);
203 }
204 return finder.result_;
205 }
206
207 protected:
208 virtual bool ShouldStopIterating(HWND hwnd) {
209 BrowserView* window = BrowserView::GetBrowserViewForNativeWindow(hwnd);
210 RECT bounds;
211 if (!window || !IsWindowVisible(hwnd) ||
212 !GetWindowRect(hwnd, &bounds)) {
213 return false;
214 }
215
216 // Check the three corners we allow docking to. We don't currently allow
217 // docking to top of window as it conflicts with docking to the tab strip.
218 if (CheckPoint(hwnd, bounds.left, (bounds.top + bounds.bottom) / 2,
219 DockInfo::LEFT_OF_WINDOW) ||
220 CheckPoint(hwnd, bounds.right - 1, (bounds.top + bounds.bottom) / 2,
221 DockInfo::RIGHT_OF_WINDOW) ||
222 CheckPoint(hwnd, (bounds.left + bounds.right) / 2, bounds.bottom - 1,
223 DockInfo::BOTTOM_OF_WINDOW)) {
224 return true;
225 }
226 return false;
227 }
228
229 private:
230 DockToWindowFinder(const gfx::Point& screen_loc,
231 const std::set<HWND>& ignore)
232 : BaseWindowFinder(ignore),
233 screen_loc_(screen_loc) {
234 HMONITOR monitor = MonitorFromPoint(screen_loc.ToPOINT(),
235 MONITOR_DEFAULTTONULL);
236 MONITORINFO monitor_info = {0};
237 monitor_info.cbSize = sizeof(MONITORINFO);
238 if (monitor && GetMonitorInfo(monitor, &monitor_info)) {
239 result_.set_monitor_bounds(gfx::Rect(monitor_info.rcWork));
240 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
241 reinterpret_cast<LPARAM>(this));
242 }
243 }
244
245 bool CheckPoint(HWND hwnd, int x, int y, DockInfo::Type type) {
246 bool in_enable_area;
247 if (DockInfo::IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) {
248 result_.set_in_enable_area(in_enable_area);
249 result_.set_window(hwnd);
250 result_.set_type(type);
251 result_.set_hot_spot(gfx::Point(x, y));
252 // Only show the hotspot if the monitor contains the bounds of the popup
253 // window. Otherwise we end with a weird situation where the popup window
254 // isn't completely visible.
255 return result_.monitor_bounds().Contains(result_.GetPopupRect());
256 }
257 return false;
258 }
259
260 // The location to look for.
261 gfx::Point screen_loc_;
262
263 // The resulting DockInfo.
264 DockInfo result_;
265
266 DISALLOW_COPY_AND_ASSIGN(DockToWindowFinder);
267 };
268
269 } // namespace
270
271 // DockInfo -------------------------------------------------------------------
272
273 // static
274 DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
275 const std::set<HWND>& ignore) {
276 if (factory_)
277 return factory_->GetDockInfoAtPoint(screen_point, ignore);
278
279 // Try docking to a window first.
280 DockInfo info = DockToWindowFinder::GetDockInfoAtPoint(screen_point, ignore);
281 if (info.type() != DockInfo::NONE)
282 return info;
283
284 // No window relative positions. Try monitor relative positions.
285 const gfx::Rect& m_bounds = info.monitor_bounds();
286 int mid_x = m_bounds.x() + m_bounds.width() / 2;
287 int mid_y = m_bounds.y() + m_bounds.height() / 2;
288
289 bool result =
290 info.CheckMonitorPoint(screen_point, mid_x, m_bounds.y(),
291 DockInfo::MAXIMIZE) ||
292 info.CheckMonitorPoint(screen_point, mid_x, m_bounds.bottom(),
293 DockInfo::BOTTOM_HALF) ||
294 info.CheckMonitorPoint(screen_point, m_bounds.x(), mid_y,
295 DockInfo::LEFT_HALF) ||
296 info.CheckMonitorPoint(screen_point, m_bounds.right(), mid_y,
297 DockInfo::RIGHT_HALF);
298
299 return info;
300 }
301
302 HWND DockInfo::GetLocalProcessWindowAtPoint(const gfx::Point& screen_point,
303 const std::set<HWND>& ignore) {
304 if (factory_)
305 return factory_->GetLocalProcessWindowAtPoint(screen_point, ignore);
306 return
307 LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
308 }
309
310 bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const {
311 RECT window_rect;
312 if (!window() || !GetWindowRect(window(), &window_rect))
313 return false;
314 *bounds = gfx::Rect(window_rect);
315 return true;
316 }
317
318 void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const {
319 if (IsZoomed(window())) {
320 // We're docking relative to another window, we need to make sure the
321 // window we're docking to isn't maximized.
322 ShowWindow(window(), SW_RESTORE | SW_SHOWNA);
323 }
324 SetWindowPos(window(), HWND_TOP, bounds.x(), bounds.y(), bounds.width(),
325 bounds.height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER);
326 }
OLDNEW
« no previous file with comments | « chrome/browser/dock_info_unittest.cc ('k') | chrome/browser/encoding_menu_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698