15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/window_finder.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/win/scoped_gdi_object.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/win/windows_version.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/screen.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/win/dpi.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/win/hwnd_util.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(USE_ASH)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)aura::Window* GetLocalProcessWindowAtPointAsh(
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Point& screen_point,
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::set<aura::Window*>& ignore);
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BaseWindowFinder -----------------------------------------------------------
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Base class used to locate a window. This is intended to be used with the
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// various win32 functions that iterate over windows.
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A subclass need only override ShouldStopIterating to determine when
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// iteration should stop.
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BaseWindowFinder {
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Creates a BaseWindowFinder with the specified set of HWNDs to ignore.
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit BaseWindowFinder(const std::set<HWND>& ignore) : ignore_(ignore) {}
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~BaseWindowFinder() {}
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Cast must match that in as_lparam().
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BaseWindowFinder* finder = reinterpret_cast<BaseWindowFinder*>(lParam);
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (finder->ignore_.find(hwnd) != finder->ignore_.end())
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return TRUE;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return finder->ShouldStopIterating(hwnd) ? FALSE : TRUE;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LPARAM as_lparam() {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Cast must match that in WindowCallbackProc().
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return reinterpret_cast<LPARAM>(static_cast<BaseWindowFinder*>(this));
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns true if iteration should stop, false if iteration should continue.
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool ShouldStopIterating(HWND window) = 0;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::set<HWND>& ignore_;
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TopMostFinder --------------------------------------------------------------
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Helper class to determine if a particular point of a window is not obscured
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// by another window.
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TopMostFinder : public BaseWindowFinder {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns true if |window| is the topmost window at the location
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |screen_loc|, not including the windows in |ignore|.
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsTopMostWindowAtPoint(HWND window,
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const gfx::Point& screen_loc,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const std::set<HWND>& ignore) {
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TopMostFinder finder(window, screen_loc, ignore);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return finder.is_top_most_;
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool ShouldStopIterating(HWND hwnd) {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (hwnd == target_) {
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Window is topmost, stop iterating.
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_top_most_ = true;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!IsWindowVisible(hwnd)) {
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // The window isn't visible, keep iterating.
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RECT r;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!GetWindowRect(hwnd, &r) || !PtInRect(&r, screen_loc_.ToPOINT())) {
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // The window doesn't contain the point, keep iterating.
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE);
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ex_styles & WS_EX_TRANSPARENT || ex_styles & WS_EX_LAYERED) {
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Mouse events fall through WS_EX_TRANSPARENT windows, so we ignore them.
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      //
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // WS_EX_LAYERED is trickier. Apps like Switcher create a totally
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // transparent WS_EX_LAYERED window that is always on top. If we don't
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // ignore WS_EX_LAYERED windows and there are totally transparent
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // WS_EX_LAYERED windows then there are effectively holes on the screen
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // that the user can't reattach tabs to. So we ignore them. This is a bit
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // problematic in so far as WS_EX_LAYERED windows need not be totally
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // transparent in which case we treat chrome windows as not being obscured
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // when they really are, but this is better than not being able to
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // reattach tabs.
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // hwnd is at the point. Make sure the point is within the windows region.
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetWindowRgn(hwnd, tmp_region_.Get()) == ERROR) {
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // There's no region on the window and the window contains the point. Stop
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // iterating.
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The region is relative to the window's rect.
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BOOL is_point_in_region = PtInRegion(tmp_region_.Get(),
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        screen_loc_.x() - r.left, screen_loc_.y() - r.top);
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tmp_region_ = CreateRectRgn(0, 0, 0, 0);
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Stop iterating if the region contains the point.
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return !!is_point_in_region;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TopMostFinder(HWND window,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                const gfx::Point& screen_loc,
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                const std::set<HWND>& ignore)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : BaseWindowFinder(ignore),
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        target_(window),
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        is_top_most_(false),
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        tmp_region_(CreateRectRgn(0, 0, 0, 0)) {
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    screen_loc_ = gfx::win::DIPToScreenPoint(screen_loc);
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EnumWindows(WindowCallbackProc, as_lparam());
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The window we're looking for.
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HWND target_;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Location of window to find in pixel coordinates.
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point screen_loc_;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Is target_ the top most window? This is initially false but set to true
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in ShouldStopIterating if target_ is passed in.
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool is_top_most_;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::win::ScopedRegion tmp_region_;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// WindowFinder ---------------------------------------------------------------
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Helper class to determine if a particular point contains a window from our
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// process.
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LocalProcessWindowFinder : public BaseWindowFinder {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns the hwnd from our process at screen_loc that is not obscured by
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // another window. Returns NULL otherwise.
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static gfx::NativeWindow GetProcessWindowAtPoint(
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const gfx::Point& screen_loc,
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::set<HWND>& ignore) {
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LocalProcessWindowFinder finder(screen_loc, ignore);
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Windows 8 has a window that appears first in the list of iterated
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // windows, yet is not visually on top of everything.
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(sky): figure out a better way to ignore this window.
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (finder.result_ &&
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ((base::win::OSInfo::GetInstance()->version() >=
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::win::VERSION_WIN8) ||
1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         TopMostFinder::IsTopMostWindowAtPoint(finder.result_,
1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                               screen_loc,
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               ignore))) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return views::DesktopWindowTreeHostWin::GetContentWindowForHWND(
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          finder.result_);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool ShouldStopIterating(HWND hwnd) {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RECT r;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (IsWindowVisible(hwnd) && GetWindowRect(hwnd, &r) &&
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        PtInRect(&r, screen_loc_.ToPOINT())) {
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result_ = hwnd;
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LocalProcessWindowFinder(const gfx::Point& screen_loc,
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           const std::set<HWND>& ignore)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : BaseWindowFinder(ignore),
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        result_(NULL) {
1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    screen_loc_ = gfx::win::DIPToScreenPoint(screen_loc);
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, as_lparam());
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Position of the mouse in pixel coordinates.
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point screen_loc_;
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The resulting window. This is initially null but set to true in
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ShouldStopIterating if an appropriate window is found.
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HWND result_;
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::set<HWND> RemapIgnoreSet(const std::set<gfx::NativeView>& ignore) {
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::set<HWND> hwnd_set;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::set<gfx::NativeView>::const_iterator it = ignore.begin();
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (; it != ignore.end(); ++it) {
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    HWND w = (*it)->GetHost()->GetAcceleratedWidget();
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (w)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      hwnd_set.insert(w);
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return hwnd_set;
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)aura::Window* GetLocalProcessWindowAtPoint(
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::HostDesktopType host_desktop_type,
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Point& screen_point,
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::set<aura::Window*>& ignore) {
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(USE_ASH)
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return GetLocalProcessWindowAtPointAsh(screen_point, ignore);
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return LocalProcessWindowFinder::GetProcessWindowAtPoint(
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          screen_point, RemapIgnoreSet(ignore));
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
232