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

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

Issue 42041: Changes docking in the following ways:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 9 months 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.h ('k') | chrome/browser/views/tabs/dragged_tab_controller.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/dock_info.h" 5 #include "chrome/browser/dock_info.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "chrome/browser/browser.h" 9 #include "chrome/browser/browser.h"
10 #include "chrome/browser/browser_list.h" 10 #include "chrome/browser/browser_list.h"
11 #include "chrome/browser/browser_window.h" 11 #include "chrome/browser/browser_window.h"
12 #include "chrome/browser/views/frame/browser_view.h" 12 #include "chrome/browser/views/frame/browser_view.h"
13 #include "chrome/browser/views/tabs/tab.h"
13 14
14 namespace { 15 namespace {
15 16
16 // Distance in pixels between the hotspot and when the hint should be shown. 17 // Distance in pixels between the hotspot and when the hint should be shown.
17 const int kHotSpotDeltaX = 100; 18 const int kHotSpotDeltaX = 120;
18 const int kHotSpotDeltaY = 80; 19 const int kHotSpotDeltaY = 120;
19 20
20 // Distance in pixels between the hotspot and when the hint should be shown 21 // Size of the popup window.
21 // and enabled. 22 const int kPopupWidth = 70;
22 const int kEnableDeltaX = 50; 23 const int kPopupHeight = 70;
23 const int kEnableDeltaY = 37;
24
25 // Distance used when maximizing. The maximize area is the whole top of the
26 // monitor.
27 const int kMaximizeHotSpotDeltaY = 100;
28 const int kMaximizeEnableDeltaY = 50;
29 24
30 // Returns true if |screen_loc| is close to the hotspot at |x|, |y|. If the 25 // Returns true if |screen_loc| is close to the hotspot at |x|, |y|. If the
31 // point is close enough to the hotspot true is returned and |in_enable_area| 26 // point is close enough to the hotspot true is returned and |in_enable_area|
32 // is set appropriately. 27 // is set appropriately.
33 bool IsCloseToPoint(const gfx::Point& screen_loc, 28 bool IsCloseToPoint(const gfx::Point& screen_loc,
34 int x, 29 int x,
35 int y, 30 int y,
36 bool* in_enable_area) { 31 bool* in_enable_area) {
37 int delta_x = abs(x - screen_loc.x()); 32 int delta_x = abs(x - screen_loc.x());
38 int delta_y = abs(y - screen_loc.y()); 33 int delta_y = abs(y - screen_loc.y());
39 *in_enable_area = (delta_x < kEnableDeltaX && delta_y < kEnableDeltaY); 34 *in_enable_area = (delta_x < kPopupWidth / 2 && delta_y < kPopupHeight / 2);
40 return *in_enable_area || (delta_x < kHotSpotDeltaX && 35 return *in_enable_area || (delta_x < kHotSpotDeltaX &&
41 delta_y < kHotSpotDeltaY); 36 delta_y < kHotSpotDeltaY);
42 } 37 }
43 38
44 // Variant of IsCloseToPoint used for monitor relative positions. 39 // Variant of IsCloseToPoint used for monitor relative positions.
45 bool IsCloseToMonitorPoint(const gfx::Point& screen_loc, 40 bool IsCloseToMonitorPoint(const gfx::Point& screen_loc,
46 int x, 41 int x,
47 int y, 42 int y,
48 DockInfo::Type type, 43 DockInfo::Type type,
49 bool* in_enable_area) { 44 bool* in_enable_area) {
50 // Because the monitor relative positions are aligned with the edge of the 45 // Because the monitor relative positions are aligned with the edge of the
51 // monitor these need to be handled differently. 46 // monitor these need to be handled differently.
52 int delta_x = abs(x - screen_loc.x()); 47 int delta_x = abs(x - screen_loc.x());
53 int delta_y = abs(y - screen_loc.y()); 48 int delta_y = abs(y - screen_loc.y());
54 49
55 int enable_delta_x = kEnableDeltaX; 50 int enable_delta_x = kPopupWidth / 2;
56 int enable_delta_y = kEnableDeltaY; 51 int enable_delta_y = kPopupHeight / 2;
57 int hot_spot_delta_x = kHotSpotDeltaX; 52 int hot_spot_delta_x = kHotSpotDeltaX;
58 int hot_spot_delta_y = kHotSpotDeltaY; 53 int hot_spot_delta_y = kHotSpotDeltaY;
59 54
60 switch (type) { 55 switch (type) {
61 case DockInfo::LEFT_HALF: 56 case DockInfo::LEFT_HALF:
62 case DockInfo::RIGHT_HALF: 57 case DockInfo::RIGHT_HALF:
63 enable_delta_x += enable_delta_x; 58 enable_delta_x += enable_delta_x;
64 hot_spot_delta_x += hot_spot_delta_x; 59 hot_spot_delta_x += hot_spot_delta_x;
65 break; 60 break;
66 61
67 62
68 case DockInfo::MAXIMIZE: 63 case DockInfo::MAXIMIZE: {
64 // Make the maximize height smaller than the tab height to avoid showing
65 // the dock indicator when close to maximized browser.
66 hot_spot_delta_y = Tab::GetMinimumUnselectedSize().height() - 1;
67 enable_delta_y = hot_spot_delta_y / 2;
68 break;
69 }
69 case DockInfo::BOTTOM_HALF: 70 case DockInfo::BOTTOM_HALF:
70 enable_delta_y += enable_delta_y; 71 enable_delta_y += enable_delta_y;
71 hot_spot_delta_y += hot_spot_delta_y; 72 hot_spot_delta_y += hot_spot_delta_y;
72 break; 73 break;
73 74
74 default: 75 default:
75 NOTREACHED(); 76 NOTREACHED();
76 return false; 77 return false;
77 } 78 }
78 *in_enable_area = (delta_x < enable_delta_x && delta_y < enable_delta_y); 79 *in_enable_area = (delta_x < enable_delta_x && delta_y < enable_delta_y);
79 bool result = (*in_enable_area || (delta_x < hot_spot_delta_x && 80 bool result = (*in_enable_area || (delta_x < hot_spot_delta_x &&
80 delta_y < hot_spot_delta_y)); 81 delta_y < hot_spot_delta_y));
81 if (type != DockInfo::MAXIMIZE) 82 if (type != DockInfo::MAXIMIZE)
82 return result; 83 return result;
83 84
84 // Make the maximize area the whole top of the monitor. 85 // Make the hot spot/enable spot for maximized windows the whole top of the
86 // monitor.
85 int max_delta_y = abs(screen_loc.y() - y); 87 int max_delta_y = abs(screen_loc.y() - y);
86 *in_enable_area = (*in_enable_area || (max_delta_y < kMaximizeEnableDeltaY)); 88 *in_enable_area = (*in_enable_area || (max_delta_y < enable_delta_y));
87 return *in_enable_area || (max_delta_y < kMaximizeHotSpotDeltaY); 89 return *in_enable_area || (max_delta_y < hot_spot_delta_y);
88 }
89
90 // Returns true if there is a maximized tabbed browser on the monitor
91 // |monitor|.
92 bool IsMaximizedTabbedBrowserOnMonitor(HMONITOR monitor) {
93 for (BrowserList::const_iterator i = BrowserList::begin();
94 i != BrowserList::end(); ++i) {
95 Browser* browser = *i;
96 if (browser->type() == Browser::TYPE_NORMAL) {
97 HWND browser_hwnd =
98 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
99 if (IsZoomed(browser_hwnd) &&
100 MonitorFromWindow(browser_hwnd, MONITOR_DEFAULTTONEAREST) ==
101 monitor) {
102 return true;
103 }
104 }
105 }
106 return false;
107 } 90 }
108 91
109 // BaseWindowFinder ----------------------------------------------------------- 92 // BaseWindowFinder -----------------------------------------------------------
110 93
111 // Base class used to locate a window. This is intended to be used with the 94 // Base class used to locate a window. This is intended to be used with the
112 // various win32 functions that iterate over windows. 95 // various win32 functions that iterate over windows.
113 // 96 //
114 // A subclass need only override ShouldStopIterating to determine when 97 // A subclass need only override ShouldStopIterating to determine when
115 // iteration should stop. 98 // iteration should stop.
116 class BaseWindowFinder { 99 class BaseWindowFinder {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 public: 252 public:
270 // Returns the DockInfo for the specified point. If there is no docking 253 // Returns the DockInfo for the specified point. If there is no docking
271 // position for the specified point the returned DockInfo has a type of NONE. 254 // position for the specified point the returned DockInfo has a type of NONE.
272 static DockInfo GetDockInfoAtPoint(const gfx::Point& screen_loc, 255 static DockInfo GetDockInfoAtPoint(const gfx::Point& screen_loc,
273 const std::set<HWND>& ignore) { 256 const std::set<HWND>& ignore) {
274 DockToWindowFinder finder(screen_loc, ignore); 257 DockToWindowFinder finder(screen_loc, ignore);
275 if (!finder.result_.hwnd() || 258 if (!finder.result_.hwnd() ||
276 !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.hwnd(), 259 !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.hwnd(),
277 finder.result_.hot_spot(), 260 finder.result_.hot_spot(),
278 ignore)) { 261 ignore)) {
279 return DockInfo(); 262 finder.result_.set_type(DockInfo::NONE);
280 } 263 }
281 return finder.result_; 264 return finder.result_;
282 } 265 }
283 266
284 protected: 267 protected:
285 virtual bool ShouldStopIterating(HWND hwnd) { 268 virtual bool ShouldStopIterating(HWND hwnd) {
286 BrowserView* window = BrowserView::GetBrowserViewForHWND(hwnd); 269 BrowserView* window = BrowserView::GetBrowserViewForHWND(hwnd);
287 CRect bounds; 270 CRect bounds;
288 if (!window || !::IsWindowVisible(hwnd) || 271 if (!window || !::IsWindowVisible(hwnd) ||
289 !::GetWindowRect(hwnd, &bounds)) { 272 !::GetWindowRect(hwnd, &bounds)) {
(...skipping 11 matching lines...) Expand all
301 return true; 284 return true;
302 } 285 }
303 return false; 286 return false;
304 } 287 }
305 288
306 private: 289 private:
307 DockToWindowFinder(const gfx::Point& screen_loc, 290 DockToWindowFinder(const gfx::Point& screen_loc,
308 const std::set<HWND>& ignore) 291 const std::set<HWND>& ignore)
309 : BaseWindowFinder(ignore), 292 : BaseWindowFinder(ignore),
310 screen_loc_(screen_loc) { 293 screen_loc_(screen_loc) {
311 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 294 HMONITOR monitor = MonitorFromPoint(screen_loc.ToPOINT(),
312 reinterpret_cast<LPARAM>(this)); 295 MONITOR_DEFAULTTONULL);
296 MONITORINFO monitor_info = {0};
297 monitor_info.cbSize = sizeof(MONITORINFO);
298 if (monitor && GetMonitorInfo(monitor, &monitor_info)) {
299 result_.set_monitor_bounds(gfx::Rect(monitor_info.rcWork));
300 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
301 reinterpret_cast<LPARAM>(this));
302 }
313 } 303 }
314 304
315 bool CheckPoint(HWND hwnd, int x, int y, DockInfo::Type type) { 305 bool CheckPoint(HWND hwnd, int x, int y, DockInfo::Type type) {
316 bool in_enable_area; 306 bool in_enable_area;
317 if (IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) { 307 if (IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) {
318 result_.set_in_enable_area(in_enable_area); 308 result_.set_in_enable_area(in_enable_area);
319 result_.set_hwnd(hwnd); 309 result_.set_hwnd(hwnd);
320 result_.set_type(type); 310 result_.set_type(type);
321 result_.set_hot_spot(gfx::Point(x, y)); 311 result_.set_hot_spot(gfx::Point(x, y));
322 return true; 312 // Only show the hotspot if the monitor contains the bounds of the popup
313 // window. Otherwise we end with a weird situation where the popup window
314 // isn't completely visible.
315 return result_.monitor_bounds().Contains(result_.GetPopupRect());
323 } 316 }
324 return false; 317 return false;
325 } 318 }
326 319
327 // The location to look for. 320 // The location to look for.
328 gfx::Point screen_loc_; 321 gfx::Point screen_loc_;
329 322
330 // The resulting DockInfo. 323 // The resulting DockInfo.
331 DockInfo result_; 324 DockInfo result_;
332 325
333 DISALLOW_COPY_AND_ASSIGN(DockToWindowFinder); 326 DISALLOW_COPY_AND_ASSIGN(DockToWindowFinder);
334 }; 327 };
335 328
336 } // namespace 329 } // namespace
337 330
338 // DockInfo ------------------------------------------------------------------- 331 // DockInfo -------------------------------------------------------------------
339 332
333 // static
340 DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point, 334 DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
341 const std::set<HWND>& ignore) { 335 const std::set<HWND>& ignore) {
342 // Try docking to a window first. 336 // Try docking to a window first.
343 DockInfo info = DockToWindowFinder::GetDockInfoAtPoint(screen_point, ignore); 337 DockInfo info = DockToWindowFinder::GetDockInfoAtPoint(screen_point, ignore);
344
345 HMONITOR monitor = MonitorFromPoint(screen_point.ToPOINT(),
346 MONITOR_DEFAULTTONULL);
347 MONITORINFO monitor_info = {0};
348 monitor_info.cbSize = sizeof(MONITORINFO);
349 if (!monitor || !GetMonitorInfo(monitor, &monitor_info)) {
350 info.type_ = NONE;
351 return info;
352 }
353 info.monitor_bounds_ = gfx::Rect(monitor_info.rcWork);
354
355 if (info.type() != DockInfo::NONE) 338 if (info.type() != DockInfo::NONE)
356 return info; 339 return info;
357 340
358 // No window relative positions. Try monitor relative positions. 341 // No window relative positions. Try monitor relative positions.
359 RECT& m_bounds = monitor_info.rcWork; 342 const gfx::Rect& m_bounds = info.monitor_bounds();
360 int mid_x = (m_bounds.left + m_bounds.right) / 2; 343 int mid_x = m_bounds.x() + m_bounds.width() / 2;
361 int mid_y = (m_bounds.top + m_bounds.bottom) / 2; 344 int mid_y = m_bounds.y() + m_bounds.height() / 2;
362 345
363 bool result = 346 bool result =
364 info.CheckMonitorPoint(monitor, screen_point, mid_x, m_bounds.top, 347 info.CheckMonitorPoint(screen_point, mid_x, m_bounds.y(),
365 DockInfo::MAXIMIZE) || 348 DockInfo::MAXIMIZE) ||
366 info.CheckMonitorPoint(monitor, screen_point, mid_x, m_bounds.bottom, 349 info.CheckMonitorPoint(screen_point, mid_x, m_bounds.bottom(),
367 DockInfo::BOTTOM_HALF) || 350 DockInfo::BOTTOM_HALF) ||
368 info.CheckMonitorPoint(monitor, screen_point, m_bounds.left, mid_y, 351 info.CheckMonitorPoint(screen_point, m_bounds.x(), mid_y,
369 DockInfo::LEFT_HALF) || 352 DockInfo::LEFT_HALF) ||
370 info.CheckMonitorPoint(monitor, screen_point, m_bounds.right, mid_y, 353 info.CheckMonitorPoint(screen_point, m_bounds.right(), mid_y,
371 DockInfo::RIGHT_HALF); 354 DockInfo::RIGHT_HALF);
372 355
373 return info; 356 return info;
374 } 357 }
375 358
359 // static
360 int DockInfo::popup_width() {
361 return kPopupWidth;
362 }
363
364 // static
365 int DockInfo::popup_height() {
366 return kPopupHeight;
367 }
368
376 HWND DockInfo::GetLocalProcessWindowAtPoint(const gfx::Point& screen_point, 369 HWND DockInfo::GetLocalProcessWindowAtPoint(const gfx::Point& screen_point,
377 const std::set<HWND>& ignore) { 370 const std::set<HWND>& ignore) {
378 return 371 return
379 LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore); 372 LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
380 } 373 }
381 374
382 bool DockInfo::IsValidForPoint(const gfx::Point& screen_point) { 375 bool DockInfo::IsValidForPoint(const gfx::Point& screen_point) {
383 if (type_ == NONE) 376 if (type_ == NONE)
384 return false; 377 return false;
385 378
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 // We're docking relative to another window, we need to make sure the 495 // We're docking relative to another window, we need to make sure the
503 // window we're docking to isn't maximized. 496 // window we're docking to isn't maximized.
504 ShowWindow(hwnd_, SW_RESTORE | SW_SHOWNA); 497 ShowWindow(hwnd_, SW_RESTORE | SW_SHOWNA);
505 } 498 }
506 ::SetWindowPos(hwnd_, HWND_TOP, other_window_bounds.x(), 499 ::SetWindowPos(hwnd_, HWND_TOP, other_window_bounds.x(),
507 other_window_bounds.y(), other_window_bounds.width(), 500 other_window_bounds.y(), other_window_bounds.width(),
508 other_window_bounds.height(), 501 other_window_bounds.height(),
509 SWP_NOACTIVATE | SWP_NOOWNERZORDER); 502 SWP_NOACTIVATE | SWP_NOOWNERZORDER);
510 } 503 }
511 504
512 bool DockInfo::CheckMonitorPoint(HMONITOR monitor, 505 gfx::Rect DockInfo::GetPopupRect() const {
513 const gfx::Point& screen_loc, 506 int x = hot_spot_.x() - popup_width() / 2;
507 int y = hot_spot_.y() - popup_height() / 2;
508 switch (type_) {
509 case LEFT_OF_WINDOW:
510 case RIGHT_OF_WINDOW:
511 case TOP_OF_WINDOW:
512 case BOTTOM_OF_WINDOW: {
513 // Constrain the popup to the monitor's bounds.
514 gfx::Rect ideal_bounds(x, y, popup_width(), popup_height());
515 ideal_bounds = ideal_bounds.AdjustToFit(monitor_bounds_);
516 return ideal_bounds;
517 }
518 case DockInfo::MAXIMIZE:
519 y += popup_height() / 2;
520 break;
521 case DockInfo::LEFT_HALF:
522 x += popup_width() / 2;
523 break;
524 case DockInfo::RIGHT_HALF:
525 x -= popup_width() / 2;
526 break;
527 case DockInfo::BOTTOM_HALF:
528 y -= popup_height() / 2;
529 break;
530
531 default:
532 NOTREACHED();
533 }
534 return gfx::Rect(x, y, popup_width(), popup_height());
535 }
536
537 bool DockInfo::CheckMonitorPoint(const gfx::Point& screen_loc,
514 int x, 538 int x,
515 int y, 539 int y,
516 Type type) { 540 Type type) {
517 if (IsCloseToMonitorPoint(screen_loc, x, y, type, &in_enable_area_) && 541 if (IsCloseToMonitorPoint(screen_loc, x, y, type, &in_enable_area_)) {
518 (type != MAXIMIZE ||
519 !IsMaximizedTabbedBrowserOnMonitor(monitor))) {
520 hot_spot_.SetPoint(x, y); 542 hot_spot_.SetPoint(x, y);
521 type_ = type; 543 type_ = type;
522 return true; 544 return true;
523 } 545 }
524 return false; 546 return false;
525 } 547 }
OLDNEW
« no previous file with comments | « chrome/browser/dock_info.h ('k') | chrome/browser/views/tabs/dragged_tab_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698