summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views
diff options
context:
space:
mode:
authorsky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-14 00:28:39 +0000
committersky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-14 00:28:39 +0000
commitd6dfe0d2402e2dbf997833f2deaf5b4a55b9b40a (patch)
tree24d69f812da224f2f9549b857a54bd967f7eac9d /chrome/browser/views
parenta4fb51b3a5e6c541d1d840c32c57dbf1c09345c0 (diff)
downloadchromium_src-d6dfe0d2402e2dbf997833f2deaf5b4a55b9b40a.zip
chromium_src-d6dfe0d2402e2dbf997833f2deaf5b4a55b9b40a.tar.gz
chromium_src-d6dfe0d2402e2dbf997833f2deaf5b4a55b9b40a.tar.bz2
Fixes bug where we were not checking if an app from another window
was on top of Chrome's topmost brower window when attempting to dock a dragged tab. BUG=1094303 TEST=see bug Review URL: http://codereview.chromium.org/10715 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views')
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.cc60
1 files changed, 52 insertions, 8 deletions
diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc
index df1cd2b..58c25127 100644
--- a/chrome/browser/views/tabs/dragged_tab_controller.cc
+++ b/chrome/browser/views/tabs/dragged_tab_controller.cc
@@ -24,7 +24,10 @@ namespace {
///////////////////////////////////////////////////////////////////////////////
// WindowFinder
-// A WindowForPoint facility that can ignore 2 provided window HWNDs.
+// A helper class that finds the topmost window from our thread under a
+// particular point. This returns NULL if we don't have a window at the
+// specified point, or there is another window from another app on top of our
+// window at the specified point.
//
class WindowFinder {
public:
@@ -32,39 +35,80 @@ class WindowFinder {
WindowFinder instance(screen_point, ignore1);
return instance.GetResult();
}
+
private:
WindowFinder(const gfx::Point& screen_point, HWND ignore1)
: screen_point_(screen_point.ToPOINT()),
ignore1_(ignore1),
- result_(NULL) {
+ result1_(NULL),
+ result2_(NULL) {
}
- static BOOL CALLBACK WindowEnumProc(HWND hwnd, LPARAM lParam) {
+ static BOOL CALLBACK EnumThreadWindowsProc(HWND hwnd, LPARAM lParam) {
WindowFinder* wf = reinterpret_cast<WindowFinder*>(lParam);
if (hwnd == wf->ignore1_)
- return true;
+ return TRUE;
if (::IsWindowVisible(hwnd)) {
CRect r;
::GetWindowRect(hwnd, &r);
if (r.PtInRect(wf->screen_point_)) {
// We always deal with the root HWND.
- wf->result_ = GetAncestor(hwnd, GA_ROOT);
+ wf->result1_ = GetAncestor(hwnd, GA_ROOT);
return FALSE;
}
}
return TRUE;
}
+ static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
+ WindowFinder* wf = reinterpret_cast<WindowFinder*>(lParam);
+ if (hwnd == wf->ignore1_)
+ return TRUE;
+
+ if (hwnd == wf->result1_) {
+ // Result from first pass is the topmost window under point. Use it.
+ wf->result2_ = hwnd;
+ return FALSE;
+ }
+
+ if (::IsWindowVisible(hwnd)) {
+ CRect r;
+ if (::GetWindowRect(hwnd, &r) && r.PtInRect(wf->screen_point_)) {
+ // Result from first pass is not the topmost window under point.
+ return FALSE;
+ }
+ }
+ return TRUE; // Keep iterating.
+ }
+
HWND GetResult() {
- EnumThreadWindows(GetCurrentThreadId(), WindowEnumProc,
+ // We take a two step approach to find the topmost window under point.
+ // Step 1: find the topmost window in our thread under point.
+ EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowsProc,
reinterpret_cast<LPARAM>(this));
- return result_;
+ if (result1_) {
+ // Step 2.
+ // We have a window under the point in our thread. Make sure there isn't
+ // another window from another app on top of our window at point.
+ // NOTE: EnumWindows iterates window from topmost window to bottommost
+ // window.
+ EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(this));
+ }
+ return result2_;
}
+ // Location we're looking for.
POINT screen_point_;
+
+ // HWND to ignore.
HWND ignore1_;
- HWND result_;
+
+ // Result from first pass. See docs in GetResult for details.
+ HWND result1_;
+
+ // Result from second pass. See docs in GetResult for details.
+ HWND result2_;
DISALLOW_EVIL_CONSTRUCTORS(WindowFinder);
};