summaryrefslogtreecommitdiffstats
path: root/chrome/browser/dock_info.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/dock_info.cc')
-rw-r--r--chrome/browser/dock_info.cc371
1 files changed, 38 insertions, 333 deletions
diff --git a/chrome/browser/dock_info.cc b/chrome/browser/dock_info.cc
index a9c2561..8c4428d 100644
--- a/chrome/browser/dock_info.cc
+++ b/chrome/browser/dock_info.cc
@@ -4,12 +4,6 @@
#include "chrome/browser/dock_info.h"
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_window.h"
-#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab.h"
namespace {
@@ -22,13 +16,16 @@ const int kHotSpotDeltaY = 120;
const int kPopupWidth = 70;
const int kPopupHeight = 70;
-// Returns true if |screen_loc| is close to the hotspot at |x|, |y|. If the
-// point is close enough to the hotspot true is returned and |in_enable_area|
-// is set appropriately.
-bool IsCloseToPoint(const gfx::Point& screen_loc,
- int x,
- int y,
- bool* in_enable_area) {
+} // namespace
+
+// static
+DockInfo::Factory* DockInfo::factory_ = NULL;
+
+// static
+bool DockInfo::IsCloseToPoint(const gfx::Point& screen_loc,
+ int x,
+ int y,
+ bool* in_enable_area) {
int delta_x = abs(x - screen_loc.x());
int delta_y = abs(y - screen_loc.y());
*in_enable_area = (delta_x < kPopupWidth / 2 && delta_y < kPopupHeight / 2);
@@ -36,12 +33,12 @@ bool IsCloseToPoint(const gfx::Point& screen_loc,
delta_y < kHotSpotDeltaY);
}
-// Variant of IsCloseToPoint used for monitor relative positions.
-bool IsCloseToMonitorPoint(const gfx::Point& screen_loc,
- int x,
- int y,
- DockInfo::Type type,
- bool* in_enable_area) {
+// static
+bool DockInfo::IsCloseToMonitorPoint(const gfx::Point& screen_loc,
+ int x,
+ int y,
+ DockInfo::Type type,
+ bool* in_enable_area) {
// Because the monitor relative positions are aligned with the edge of the
// monitor these need to be handled differently.
int delta_x = abs(x - screen_loc.x());
@@ -89,279 +86,6 @@ bool IsCloseToMonitorPoint(const gfx::Point& screen_loc,
return *in_enable_area || (max_delta_y < hot_spot_delta_y);
}
-// BaseWindowFinder -----------------------------------------------------------
-
-// Base class used to locate a window. This is intended to be used with the
-// various win32 functions that iterate over windows.
-//
-// A subclass need only override ShouldStopIterating to determine when
-// iteration should stop.
-class BaseWindowFinder {
- public:
- // Creates a BaseWindowFinder with the specified set of HWNDs to ignore.
- BaseWindowFinder(const std::set<HWND>& ignore) : ignore_(ignore) {}
- virtual ~BaseWindowFinder() {}
-
- protected:
- // Returns true if iteration should stop, false if iteration should continue.
- virtual bool ShouldStopIterating(HWND window) = 0;
-
- static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
- BaseWindowFinder* finder = reinterpret_cast<BaseWindowFinder*>(lParam);
- if (finder->ignore_.find(hwnd) != finder->ignore_.end())
- return TRUE;
-
- return finder->ShouldStopIterating(hwnd) ? FALSE : TRUE;
- }
-
- private:
- const std::set<HWND>& ignore_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
-};
-
-// TopMostFinder --------------------------------------------------------------
-
-// Helper class to determine if a particular point of a window is not obscured
-// by another window.
-class TopMostFinder : public BaseWindowFinder {
- public:
- // Returns true if |window| is the topmost window at the location
- // |screen_loc|, not including the windows in |ignore|.
- static bool IsTopMostWindowAtPoint(HWND window,
- const gfx::Point& screen_loc,
- const std::set<HWND>& ignore) {
- TopMostFinder finder(window, screen_loc, ignore);
- return finder.is_top_most_;
- }
-
- virtual bool ShouldStopIterating(HWND hwnd) {
- if (hwnd == target_) {
- // Window is topmost, stop iterating.
- is_top_most_ = true;
- return true;
- }
-
- if (!::IsWindowVisible(hwnd)) {
- // The window isn't visible, keep iterating.
- return false;
- }
-
- CRect r;
- if (!::GetWindowRect(hwnd, &r) || !r.PtInRect(screen_loc_.ToPOINT())) {
- // The window doesn't contain the point, keep iterating.
- return false;
- }
-
- // hwnd is at the point. Make sure the point is within the windows region.
- if (GetWindowRgn(hwnd, tmp_region_.Get()) == ERROR) {
- // There's no region on the window and the window contains the point. Stop
- // iterating.
- return true;
- }
-
- // The region is relative to the window's rect.
- BOOL is_point_in_region = PtInRegion(tmp_region_.Get(),
- screen_loc_.x() - r.left, screen_loc_.y() - r.top);
- tmp_region_ = CreateRectRgn(0, 0, 0, 0);
- // Stop iterating if the region contains the point.
- return !!is_point_in_region;
- }
-
- private:
- TopMostFinder(HWND window,
- const gfx::Point& screen_loc,
- const std::set<HWND>& ignore)
- : BaseWindowFinder(ignore),
- target_(window),
- screen_loc_(screen_loc),
- is_top_most_(false),
- tmp_region_(CreateRectRgn(0, 0, 0, 0)) {
- EnumWindows(WindowCallbackProc, reinterpret_cast<LPARAM>(this));
- }
-
- // The window we're looking for.
- HWND target_;
-
- // Location of window to find.
- gfx::Point screen_loc_;
-
- // Is target_ the top most window? This is initially false but set to true
- // in ShouldStopIterating if target_ is passed in.
- bool is_top_most_;
-
- ScopedHRGN tmp_region_;
-
- DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
-};
-
-// WindowFinder ---------------------------------------------------------------
-
-// Helper class to determine if a particular point contains a window from our
-// process.
-class LocalProcessWindowFinder : public BaseWindowFinder {
- public:
- // Returns the hwnd from our process at screen_loc that is not obscured by
- // another window. Returns NULL otherwise.
- static HWND GetProcessWindowAtPoint(const gfx::Point& screen_loc,
- const std::set<HWND>& ignore) {
- LocalProcessWindowFinder finder(screen_loc, ignore);
- if (finder.result_ &&
- TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
- ignore)) {
- return finder.result_;
- }
- return NULL;
- }
-
- protected:
- virtual bool ShouldStopIterating(HWND hwnd) {
- CRect r;
- if (::IsWindowVisible(hwnd) && ::GetWindowRect(hwnd, &r) &&
- r.PtInRect(screen_loc_.ToPOINT())) {
- result_ = hwnd;
- return true;
- }
- return false;
- }
-
- private:
- LocalProcessWindowFinder(const gfx::Point& screen_loc,
- const std::set<HWND>& ignore)
- : BaseWindowFinder(ignore),
- screen_loc_(screen_loc),
- result_(NULL) {
- EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
- reinterpret_cast<LPARAM>(this));
- }
-
- // Position of the mouse.
- gfx::Point screen_loc_;
-
- // The resulting window. This is initially null but set to true in
- // ShouldStopIterating if an appropriate window is found.
- HWND result_;
-
- DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
-};
-
-// DockToWindowFinder ---------------------------------------------------------
-
-// Helper class for creating a DockInfo from a specified point.
-class DockToWindowFinder : public BaseWindowFinder {
- public:
- // Returns the DockInfo for the specified point. If there is no docking
- // position for the specified point the returned DockInfo has a type of NONE.
- static DockInfo GetDockInfoAtPoint(const gfx::Point& screen_loc,
- const std::set<HWND>& ignore) {
- DockToWindowFinder finder(screen_loc, ignore);
- if (!finder.result_.hwnd() ||
- !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.hwnd(),
- finder.result_.hot_spot(),
- ignore)) {
- finder.result_.set_type(DockInfo::NONE);
- }
- return finder.result_;
- }
-
- protected:
- virtual bool ShouldStopIterating(HWND hwnd) {
- BrowserView* window = BrowserView::GetBrowserViewForHWND(hwnd);
- CRect bounds;
- if (!window || !::IsWindowVisible(hwnd) ||
- !::GetWindowRect(hwnd, &bounds)) {
- return false;
- }
-
- // Check the three corners we allow docking to. We don't currently allow
- // docking to top of window as it conflicts with docking to the tab strip.
- if (CheckPoint(hwnd, bounds.left, (bounds.top + bounds.bottom) / 2,
- DockInfo::LEFT_OF_WINDOW) ||
- CheckPoint(hwnd, bounds.right - 1, (bounds.top + bounds.bottom) / 2,
- DockInfo::RIGHT_OF_WINDOW) ||
- CheckPoint(hwnd, (bounds.left + bounds.right) / 2, bounds.bottom - 1,
- DockInfo::BOTTOM_OF_WINDOW)) {
- return true;
- }
- return false;
- }
-
- private:
- DockToWindowFinder(const gfx::Point& screen_loc,
- const std::set<HWND>& ignore)
- : BaseWindowFinder(ignore),
- screen_loc_(screen_loc) {
- HMONITOR monitor = MonitorFromPoint(screen_loc.ToPOINT(),
- MONITOR_DEFAULTTONULL);
- MONITORINFO monitor_info = {0};
- monitor_info.cbSize = sizeof(MONITORINFO);
- if (monitor && GetMonitorInfo(monitor, &monitor_info)) {
- result_.set_monitor_bounds(gfx::Rect(monitor_info.rcWork));
- EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc,
- reinterpret_cast<LPARAM>(this));
- }
- }
-
- bool CheckPoint(HWND hwnd, int x, int y, DockInfo::Type type) {
- bool in_enable_area;
- if (IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) {
- result_.set_in_enable_area(in_enable_area);
- result_.set_hwnd(hwnd);
- result_.set_type(type);
- result_.set_hot_spot(gfx::Point(x, y));
- // Only show the hotspot if the monitor contains the bounds of the popup
- // window. Otherwise we end with a weird situation where the popup window
- // isn't completely visible.
- return result_.monitor_bounds().Contains(result_.GetPopupRect());
- }
- return false;
- }
-
- // The location to look for.
- gfx::Point screen_loc_;
-
- // The resulting DockInfo.
- DockInfo result_;
-
- DISALLOW_COPY_AND_ASSIGN(DockToWindowFinder);
-};
-
-} // namespace
-
-// DockInfo -------------------------------------------------------------------
-
-// static
-DockInfo::Factory* DockInfo::factory_ = NULL;
-
-// static
-DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
- const std::set<HWND>& ignore) {
- if (factory_)
- return factory_->GetDockInfoAtPoint(screen_point, ignore);
-
- // Try docking to a window first.
- DockInfo info = DockToWindowFinder::GetDockInfoAtPoint(screen_point, ignore);
- if (info.type() != DockInfo::NONE)
- return info;
-
- // No window relative positions. Try monitor relative positions.
- const gfx::Rect& m_bounds = info.monitor_bounds();
- int mid_x = m_bounds.x() + m_bounds.width() / 2;
- int mid_y = m_bounds.y() + m_bounds.height() / 2;
-
- bool result =
- info.CheckMonitorPoint(screen_point, mid_x, m_bounds.y(),
- DockInfo::MAXIMIZE) ||
- info.CheckMonitorPoint(screen_point, mid_x, m_bounds.bottom(),
- DockInfo::BOTTOM_HALF) ||
- info.CheckMonitorPoint(screen_point, m_bounds.x(), mid_y,
- DockInfo::LEFT_HALF) ||
- info.CheckMonitorPoint(screen_point, m_bounds.right(), mid_y,
- DockInfo::RIGHT_HALF);
-
- return info;
-}
-
// static
int DockInfo::popup_width() {
return kPopupWidth;
@@ -372,19 +96,11 @@ int DockInfo::popup_height() {
return kPopupHeight;
}
-HWND DockInfo::GetLocalProcessWindowAtPoint(const gfx::Point& screen_point,
- const std::set<HWND>& ignore) {
- if (factory_)
- return factory_->GetLocalProcessWindowAtPoint(screen_point, ignore);
- return
- LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
-}
-
bool DockInfo::IsValidForPoint(const gfx::Point& screen_point) {
if (type_ == NONE)
return false;
- if (hwnd_) {
+ if (window_) {
return IsCloseToPoint(screen_point, hot_spot_.x(), hot_spot_.y(),
&in_enable_area_);
}
@@ -399,38 +115,36 @@ bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
if (type_ == NONE || !in_enable_area_)
return false;
- RECT window_rect;
- if (hwnd_ && !GetWindowRect(hwnd_, &window_rect))
+ gfx::Rect window_bounds;
+ if (window_ && !GetWindowBounds(&window_bounds))
return false;
int half_m_width = (monitor_bounds_.right() - monitor_bounds_.x()) / 2;
int half_m_height = (monitor_bounds_.bottom() - monitor_bounds_.y()) / 2;
- bool unmaximize_other_window = false;
*maximize_new_window = false;
switch (type_) {
case LEFT_OF_WINDOW:
- new_window_bounds->SetRect(monitor_bounds_.x(), window_rect.top,
- half_m_width, window_rect.bottom - window_rect.top);
+ new_window_bounds->SetRect(monitor_bounds_.x(), window_bounds.y(),
+ half_m_width, window_bounds.height());
break;
case RIGHT_OF_WINDOW:
new_window_bounds->SetRect(monitor_bounds_.x() + half_m_width,
- window_rect.top, half_m_width, window_rect.bottom - window_rect.top);
+ window_bounds.y(), half_m_width,
+ window_bounds.height());
break;
case TOP_OF_WINDOW:
- new_window_bounds->SetRect(window_rect.left, monitor_bounds_.y(),
- window_rect.right - window_rect.left,
- half_m_height);
+ new_window_bounds->SetRect(window_bounds.x(), monitor_bounds_.y(),
+ window_bounds.width(), half_m_height);
break;
case BOTTOM_OF_WINDOW:
- new_window_bounds->SetRect(window_rect.left,
+ new_window_bounds->SetRect(window_bounds.x(),
monitor_bounds_.y() + half_m_height,
- window_rect.right - window_rect.left,
- half_m_height);
+ window_bounds.width(), half_m_height);
break;
case LEFT_HALF:
@@ -463,8 +177,8 @@ void DockInfo::AdjustOtherWindowBounds() const {
if (!in_enable_area_)
return;
- RECT window_rect;
- if (!hwnd_ || !GetWindowRect(hwnd_, &window_rect))
+ gfx::Rect window_bounds;
+ if (!window_ || !GetWindowBounds(&window_bounds))
return;
gfx::Rect other_window_bounds;
@@ -474,40 +188,31 @@ void DockInfo::AdjustOtherWindowBounds() const {
switch (type_) {
case LEFT_OF_WINDOW:
other_window_bounds.SetRect(monitor_bounds_.x() + half_m_width,
- window_rect.top, half_m_width, window_rect.bottom - window_rect.top);
+ window_bounds.y(), half_m_width,
+ window_bounds.height());
break;
case RIGHT_OF_WINDOW:
- other_window_bounds.SetRect(monitor_bounds_.x(), window_rect.top,
- half_m_width, window_rect.bottom - window_rect.top);
+ other_window_bounds.SetRect(monitor_bounds_.x(), window_bounds.y(),
+ half_m_width, window_bounds.height());
break;
case TOP_OF_WINDOW:
- other_window_bounds.SetRect(window_rect.left,
+ other_window_bounds.SetRect(window_bounds.x(),
monitor_bounds_.y() + half_m_height,
- window_rect.right - window_rect.left,
- half_m_height);
+ window_bounds.width(), half_m_height);
break;
case BOTTOM_OF_WINDOW:
- other_window_bounds.SetRect(window_rect.left, monitor_bounds_.y(),
- window_rect.right - window_rect.left,
- half_m_height);
+ other_window_bounds.SetRect(window_bounds.x(), monitor_bounds_.y(),
+ window_bounds.width(), half_m_height);
break;
default:
return;
}
- if (IsZoomed(hwnd_)) {
- // We're docking relative to another window, we need to make sure the
- // window we're docking to isn't maximized.
- ShowWindow(hwnd_, SW_RESTORE | SW_SHOWNA);
- }
- ::SetWindowPos(hwnd_, HWND_TOP, other_window_bounds.x(),
- other_window_bounds.y(), other_window_bounds.width(),
- other_window_bounds.height(),
- SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+ SizeOtherWindowTo(other_window_bounds);
}
gfx::Rect DockInfo::GetPopupRect() const {