| Index: chrome/browser/dock_info_win.cc
|
| ===================================================================
|
| --- chrome/browser/dock_info_win.cc (revision 68008)
|
| +++ chrome/browser/dock_info_win.cc (working copy)
|
| @@ -1,326 +0,0 @@
|
| -// Copyright (c) 2010 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/dock_info.h"
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "chrome/browser/browser_list.h"
|
| -#include "chrome/browser/browser_window.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/views/frame/browser_view.h"
|
| -#include "chrome/browser/views/tabs/tab.h"
|
| -
|
| -namespace {
|
| -
|
| -// 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.
|
| - explicit 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;
|
| - }
|
| -
|
| - RECT r;
|
| - if (!GetWindowRect(hwnd, &r) || !PtInRect(&r, screen_loc_.ToPOINT())) {
|
| - // The window doesn't contain the point, keep iterating.
|
| - return false;
|
| - }
|
| -
|
| - LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE);
|
| - if (ex_styles & WS_EX_TRANSPARENT || ex_styles & WS_EX_LAYERED) {
|
| - // Mouse events fall through WS_EX_TRANSPARENT windows, so we ignore them.
|
| - //
|
| - // WS_EX_LAYERED is trickier. Apps like Switcher create a totally
|
| - // transparent WS_EX_LAYERED window that is always on top. If we don't
|
| - // ignore WS_EX_LAYERED windows and there are totally transparent
|
| - // WS_EX_LAYERED windows then there are effectively holes on the screen
|
| - // that the user can't reattach tabs to. So we ignore them. This is a bit
|
| - // problematic in so far as WS_EX_LAYERED windows need not be totally
|
| - // transparent in which case we treat chrome windows as not being obscured
|
| - // when they really are, but this is better than not being able to
|
| - // reattach tabs.
|
| - 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_;
|
| -
|
| - ScopedRegion 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) {
|
| - RECT r;
|
| - if (IsWindowVisible(hwnd) && GetWindowRect(hwnd, &r) &&
|
| - PtInRect(&r, 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_.window() ||
|
| - !TopMostFinder::IsTopMostWindowAtPoint(finder.result_.window(),
|
| - finder.result_.hot_spot(),
|
| - ignore)) {
|
| - finder.result_.set_type(DockInfo::NONE);
|
| - }
|
| - return finder.result_;
|
| - }
|
| -
|
| - protected:
|
| - virtual bool ShouldStopIterating(HWND hwnd) {
|
| - BrowserView* window = BrowserView::GetBrowserViewForNativeWindow(hwnd);
|
| - RECT 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 (DockInfo::IsCloseToPoint(screen_loc_, x, y, &in_enable_area)) {
|
| - result_.set_in_enable_area(in_enable_area);
|
| - result_.set_window(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 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;
|
| -}
|
| -
|
| -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::GetWindowBounds(gfx::Rect* bounds) const {
|
| - RECT window_rect;
|
| - if (!window() || !GetWindowRect(window(), &window_rect))
|
| - return false;
|
| - *bounds = gfx::Rect(window_rect);
|
| - return true;
|
| -}
|
| -
|
| -void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const {
|
| - if (IsZoomed(window())) {
|
| - // We're docking relative to another window, we need to make sure the
|
| - // window we're docking to isn't maximized.
|
| - ShowWindow(window(), SW_RESTORE | SW_SHOWNA);
|
| - }
|
| - SetWindowPos(window(), HWND_TOP, bounds.x(), bounds.y(), bounds.width(),
|
| - bounds.height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER);
|
| -}
|
|
|