1 // Copyright (c) 2012 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"
9 #include "base/logging.h"
10 #include "chrome/browser/ui/browser_list.h"
11 #include "chrome/browser/ui/browser_window.h"
12 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
13 #include "chrome/browser/ui/gtk/gtk_util.h"
14 #include "chrome/browser/ui/gtk/tabs/tab_gtk.h"
15 #include "chrome/browser/ui/host_desktop.h"
16 #include "ui/base/x/x11_util.h"
17 #include "ui/gfx/native_widget_types.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
<GtkWidget
*>& ignore
) {
27 std::set
<GtkWidget
*>::iterator iter
;
28 for (iter
= ignore
.begin(); iter
!= ignore
.end(); iter
++) {
29 XID xid
= ui::GetX11WindowFromGtkWidget(*iter
);
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
<GtkWidget
*>& 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 if (ui::WindowContainsPoint(window
, screen_loc_
))
92 TopMostFinder(XID window
,
93 const gfx::Point
& screen_loc
,
94 const std::set
<GtkWidget
*>& ignore
)
95 : BaseWindowFinder(ignore
),
97 screen_loc_(screen_loc
),
99 ui::EnumerateTopLevelWindows(this);
102 // The window we're looking for.
105 // Location of window to find.
106 gfx::Point screen_loc_
;
108 // Is target_ the top most window? This is initially false but set to true
109 // in ShouldStopIterating if target_ is passed in.
112 DISALLOW_COPY_AND_ASSIGN(TopMostFinder
);
115 ////////////////////////////////////////////////////////////////////////////////
116 // LocalProcessWindowFinder
118 // Helper class to determine if a particular point of a window from our process
119 // is not obscured by another window.
120 class LocalProcessWindowFinder
: public BaseWindowFinder
{
122 // Returns the XID from our process at screen_loc that is not obscured by
123 // another window. Returns 0 otherwise.
124 static XID
GetProcessWindowAtPoint(const gfx::Point
& screen_loc
,
125 const std::set
<GtkWidget
*>& ignore
) {
126 LocalProcessWindowFinder
finder(screen_loc
, ignore
);
127 if (finder
.result_
&&
128 TopMostFinder::IsTopMostWindowAtPoint(finder
.result_
, screen_loc
,
130 return finder
.result_
;
136 virtual bool ShouldStopIterating(XID window
) OVERRIDE
{
137 if (BaseWindowFinder::ShouldIgnoreWindow(window
))
140 // Check if this window is in our process.
141 if (!BrowserWindowGtk::GetBrowserWindowForXID(window
))
144 if (!ui::IsWindowVisible(window
))
147 if (ui::WindowContainsPoint(window
, screen_loc_
)) {
156 LocalProcessWindowFinder(const gfx::Point
& screen_loc
,
157 const std::set
<GtkWidget
*>& ignore
)
158 : BaseWindowFinder(ignore
),
159 screen_loc_(screen_loc
),
161 ui::EnumerateTopLevelWindows(this);
164 // Position of the mouse.
165 gfx::Point screen_loc_
;
167 // The resulting window. This is initially null but set to true in
168 // ShouldStopIterating if an appropriate window is found.
171 DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder
);
175 DockInfo
DockInfo::GetDockInfoAtPoint(chrome::HostDesktopType host_desktop_type
,
176 const gfx::Point
& screen_point
,
177 const std::set
<GtkWidget
*>& ignore
) {
183 GtkWindow
* DockInfo::GetLocalProcessWindowAtPoint(
184 chrome::HostDesktopType host_desktop_type
,
185 const gfx::Point
& screen_point
,
186 const std::set
<GtkWidget
*>& ignore
) {
188 LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point
, ignore
);
189 return BrowserWindowGtk::GetBrowserWindowForXID(xid
);
192 bool DockInfo::GetWindowBounds(gfx::Rect
* bounds
) const {
197 gtk_window_get_position(window(), &x
, &y
);
198 gtk_window_get_size(window(), &w
, &h
);
199 bounds
->SetRect(x
, y
, w
, h
);
203 void DockInfo::SizeOtherWindowTo(const gfx::Rect
& bounds
) const {
204 gtk_window_move(window(), bounds
.x(), bounds
.y());
205 gtk_window_resize(window(), bounds
.width(), bounds
.height());
209 int DockInfo::GetHotSpotDeltaY() {
210 return TabGtk::GetMinimumUnselectedSize().height() - 1;