- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / aura / tabs / dock_info_auralinux.cc
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.
4
5 #include "chrome/browser/ui/tabs/dock_info.h"
6
7 #include "chrome/browser/ui/host_desktop.h"
8 #include "ui/aura/root_window.h"
9 #include "ui/aura/window.h"
10 #if defined(USE_X11)
11 #include "ui/base/x/x11_util.h"
12 #endif
13
14 #if !defined(OS_CHROMEOS) && defined(USE_X11)
15 #include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
16
17 namespace {
18
19 ////////////////////////////////////////////////////////////////////////////////
20 // BaseWindowFinder
21 //
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 {
25  public:
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();
30       ignore_.insert(xid);
31     }
32   }
33
34   virtual ~BaseWindowFinder() {}
35
36  protected:
37   // Returns true if |window| is in the ignore list.
38   bool ShouldIgnoreWindow(XID window) {
39     return (ignore_.find(window) != ignore_.end());
40   }
41
42   // Returns true if iteration should stop, false otherwise.
43   virtual bool ShouldStopIterating(XID window) OVERRIDE {
44     return false;
45   }
46
47  private:
48   std::set<XID> ignore_;
49
50   DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
51 };
52
53 ////////////////////////////////////////////////////////////////////////////////
54 // TopMostFinder
55 //
56 // Helper class to determine if a particular point of a window is not obscured
57 // by another window.
58 class TopMostFinder : public BaseWindowFinder {
59  public:
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_;
67   }
68
69  protected:
70   virtual bool ShouldStopIterating(XID window) OVERRIDE {
71     if (BaseWindowFinder::ShouldIgnoreWindow(window))
72       return false;
73
74     if (window == target_) {
75       // Window is topmost, stop iterating.
76       is_top_most_ = true;
77       return true;
78     }
79
80     if (!ui::IsWindowVisible(window)) {
81       // The window isn't visible, keep iterating.
82       return false;
83     }
84
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_);
90   }
91
92  private:
93   TopMostFinder(XID window,
94                 const gfx::Point& screen_loc,
95                 const std::set<aura::Window*>& ignore)
96     : BaseWindowFinder(ignore),
97       target_(window),
98       screen_loc_(screen_loc),
99       is_top_most_(false) {
100     ui::EnumerateTopLevelWindows(this);
101   }
102
103   // The window we're looking for.
104   XID target_;
105
106   // Location of window to find.
107   gfx::Point screen_loc_;
108
109   // Is target_ the top most window? This is initially false but set to true
110   // in ShouldStopIterating if target_ is passed in.
111   bool is_top_most_;
112
113   DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
114 };
115
116 ////////////////////////////////////////////////////////////////////////////////
117 // LocalProcessWindowFinder
118 //
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 {
122  public:
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,
130                                               ignore)) {
131       return finder.result_;
132     }
133     return 0;
134   }
135
136  protected:
137   virtual bool ShouldStopIterating(XID window) OVERRIDE {
138     if (BaseWindowFinder::ShouldIgnoreWindow(window))
139       return false;
140
141     // Check if this window is in our process.
142     if (!aura::RootWindow::GetForAcceleratedWidget(window))
143       return false;
144
145     if (!ui::IsWindowVisible(window))
146       return false;
147
148     if (ui::WindowContainsPoint(window, screen_loc_)) {
149       result_ = window;
150       return true;
151     }
152
153     return false;
154   }
155
156  private:
157   LocalProcessWindowFinder(const gfx::Point& screen_loc,
158                            const std::set<aura::Window*>& ignore)
159     : BaseWindowFinder(ignore),
160       screen_loc_(screen_loc),
161       result_(0) {
162     ui::EnumerateTopLevelWindows(this);
163   }
164
165   // Position of the mouse.
166   gfx::Point screen_loc_;
167
168   // The resulting window. This is initially null but set to true in
169   // ShouldStopIterating if an appropriate window is found.
170   XID result_;
171
172   DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
173 };
174
175 }  // namespace
176
177 // static
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
183   // is.
184   XID xid =
185       LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
186   return views::DesktopRootWindowHostX11::GetContentWindowForXID(xid);
187 }
188 #else
189 // static
190 gfx::NativeView DockInfo::GetLocalProcessWindowAtPoint(
191     chrome::HostDesktopType host_desktop_type,
192     const gfx::Point& screen_point,
193     const std::set<gfx::NativeView>& ignore) {
194
195   // TODO(vignatti):
196   NOTIMPLEMENTED();
197   return NULL;
198 }
199 #endif
200
201 // static
202 DockInfo DockInfo::GetDockInfoAtPoint(chrome::HostDesktopType host_desktop_type,
203                                       const gfx::Point& screen_point,
204                                       const std::set<gfx::NativeView>& ignore) {
205   // TODO(beng):
206   NOTIMPLEMENTED();
207   return DockInfo();
208 }
209
210 bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const {
211   if (!window())
212     return false;
213   *bounds = window_->bounds();
214   return true;
215 }
216
217 void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const {
218   window_->SetBounds(bounds);
219 }