1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/tabs/dock_info.h"
7 #include "chrome/browser/ui/host_desktop.h"
8 #include "ui/aura/root_window.h"
9 #include "ui/aura/window.h"
11 #include "ui/base/x/x11_util.h"
14 #if !defined(OS_CHROMEOS) && defined(USE_X11)
15 #include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
19 ////////////////////////////////////////////////////////////////////////////////
22 // Base class used to locate a window. A subclass need only override
23 // ShouldStopIterating to determine when iteration should stop.
24 class BaseWindowFinder : public ui::EnumerateWindowsDelegate {
26 explicit BaseWindowFinder(const std::set<aura::Window*>& ignore) {
27 std::set<aura::Window*>::iterator iter;
28 for (iter = ignore.begin(); iter != ignore.end(); iter++) {
29 XID xid = (*iter)->GetDispatcher()->GetAcceleratedWidget();
34 virtual ~BaseWindowFinder() {}
37 // Returns true if |window| is in the ignore list.
38 bool ShouldIgnoreWindow(XID window) {
39 return (ignore_.find(window) != ignore_.end());
42 // Returns true if iteration should stop, false otherwise.
43 virtual bool ShouldStopIterating(XID window) OVERRIDE {
48 std::set<XID> ignore_;
50 DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
53 ////////////////////////////////////////////////////////////////////////////////
56 // Helper class to determine if a particular point of a window is not obscured
58 class TopMostFinder : public BaseWindowFinder {
60 // Returns true if |window| is not obscured by another window at the
61 // location |screen_loc|, not including the windows in |ignore|.
62 static bool IsTopMostWindowAtPoint(XID window,
63 const gfx::Point& screen_loc,
64 const std::set<aura::Window*>& ignore) {
65 TopMostFinder finder(window, screen_loc, ignore);
66 return finder.is_top_most_;
70 virtual bool ShouldStopIterating(XID window) OVERRIDE {
71 if (BaseWindowFinder::ShouldIgnoreWindow(window))
74 if (window == target_) {
75 // Window is topmost, stop iterating.
80 if (!ui::IsWindowVisible(window)) {
81 // The window isn't visible, keep iterating.
85 // At this point we haven't found our target window, so this window is
86 // higher in the z-order than the target window. If this window contains
87 // the point, then we can stop the search now because this window is
88 // obscuring the target window at this point.
89 return ui::WindowContainsPoint(window, screen_loc_);
93 TopMostFinder(XID window,
94 const gfx::Point& screen_loc,
95 const std::set<aura::Window*>& ignore)
96 : BaseWindowFinder(ignore),
98 screen_loc_(screen_loc),
100 ui::EnumerateTopLevelWindows(this);
103 // The window we're looking for.
106 // Location of window to find.
107 gfx::Point screen_loc_;
109 // Is target_ the top most window? This is initially false but set to true
110 // in ShouldStopIterating if target_ is passed in.
113 DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
116 ////////////////////////////////////////////////////////////////////////////////
117 // LocalProcessWindowFinder
119 // Helper class to determine if a particular point of a window from our process
120 // is not obscured by another window.
121 class LocalProcessWindowFinder : public BaseWindowFinder {
123 // Returns the XID from our process at screen_loc that is not obscured by
124 // another window. Returns 0 otherwise.
125 static XID GetProcessWindowAtPoint(const gfx::Point& screen_loc,
126 const std::set<aura::Window*>& ignore) {
127 LocalProcessWindowFinder finder(screen_loc, ignore);
128 if (finder.result_ &&
129 TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
131 return finder.result_;
137 virtual bool ShouldStopIterating(XID window) OVERRIDE {
138 if (BaseWindowFinder::ShouldIgnoreWindow(window))
141 // Check if this window is in our process.
142 if (!aura::RootWindow::GetForAcceleratedWidget(window))
145 if (!ui::IsWindowVisible(window))
148 if (ui::WindowContainsPoint(window, screen_loc_)) {
157 LocalProcessWindowFinder(const gfx::Point& screen_loc,
158 const std::set<aura::Window*>& ignore)
159 : BaseWindowFinder(ignore),
160 screen_loc_(screen_loc),
162 ui::EnumerateTopLevelWindows(this);
165 // Position of the mouse.
166 gfx::Point screen_loc_;
168 // The resulting window. This is initially null but set to true in
169 // ShouldStopIterating if an appropriate window is found.
172 DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
178 gfx::NativeView DockInfo::GetLocalProcessWindowAtPoint(
179 chrome::HostDesktopType host_desktop_type,
180 const gfx::Point& screen_point,
181 const std::set<gfx::NativeView>& ignore) {
182 // The X11 server is the canonical state of what the window stacking order
185 LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
186 return views::DesktopRootWindowHostX11::GetContentWindowForXID(xid);
190 gfx::NativeView DockInfo::GetLocalProcessWindowAtPoint(
191 chrome::HostDesktopType host_desktop_type,
192 const gfx::Point& screen_point,
193 const std::set<gfx::NativeView>& ignore) {
202 DockInfo DockInfo::GetDockInfoAtPoint(chrome::HostDesktopType host_desktop_type,
203 const gfx::Point& screen_point,
204 const std::set<gfx::NativeView>& ignore) {
210 bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const {
213 *bounds = window_->bounds();
217 void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const {
218 window_->SetBounds(bounds);