summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/dock_info.h2
-rw-r--r--chrome/browser/dock_info_gtk.cc185
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc43
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h21
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc27
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h11
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_gtk.h2
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc48
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc4
-rw-r--r--chrome/chrome.gyp5
-rw-r--r--chrome/common/x11_util.cc42
-rw-r--r--chrome/common/x11_util.h27
12 files changed, 372 insertions, 45 deletions
diff --git a/chrome/browser/dock_info.h b/chrome/browser/dock_info.h
index a2beccb..4f6d476 100644
--- a/chrome/browser/dock_info.h
+++ b/chrome/browser/dock_info.h
@@ -34,7 +34,7 @@ class DockInfo {
const std::set<gfx::NativeView>& ignore) = 0;
};
- // Possible dock positions.
+ // Possible dock positions.
enum Type {
// Indicates there is no valid dock position for the current location.
NONE,
diff --git a/chrome/browser/dock_info_gtk.cc b/chrome/browser/dock_info_gtk.cc
index e64b966..aadb417 100644
--- a/chrome/browser/dock_info_gtk.cc
+++ b/chrome/browser/dock_info_gtk.cc
@@ -8,8 +8,172 @@
#include "base/gfx/native_widget_types.h"
#include "base/logging.h"
+#include "base/task.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
+#include "chrome/common/x11_util.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// BaseWindowFinder
+//
+// Base class used to locate a window. A subclass need only override
+// ShouldStopIterating to determine when iteration should stop.
+class BaseWindowFinder : public x11_util::EnumerateWindowsDelegate {
+ public:
+ explicit BaseWindowFinder(const std::set<GtkWidget*>& ignore) {
+ std::set<GtkWidget*>::iterator iter;
+ for (iter = ignore.begin(); iter != ignore.end(); iter++) {
+ XID xid = x11_util::GetX11WindowFromGtkWidget(*iter);
+ ignore_.insert(xid);
+ }
+ }
+
+ virtual ~BaseWindowFinder() {}
+
+ protected:
+ // Returns true if iteration should stop, false otherwise.
+ virtual bool ShouldStopIterating(XID window) {
+ return (ignore_.find(window) != ignore_.end());
+ }
+
+ private:
+ std::set<XID> ignore_;
+
+ DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// TopMostFinder
+//
+// Helper class to determine if a particular point of a window is not obscured
+// by another window.
+class TopMostFinder : public BaseWindowFinder {
+ public:
+ // Returns true if |window| is not obscured by another window at the
+ // location |screen_loc|, not including the windows in |ignore|.
+ static bool IsTopMostWindowAtPoint(XID window,
+ const gfx::Point& screen_loc,
+ const std::set<GtkWidget*>& ignore) {
+ TopMostFinder finder(window, screen_loc, ignore);
+ return finder.is_top_most_;
+ }
+
+ protected:
+ virtual bool ShouldStopIterating(XID window) {
+ if (BaseWindowFinder::ShouldStopIterating(window))
+ return true;
+
+ if (window == target_) {
+ // Window is topmost, stop iterating.
+ is_top_most_ = true;
+ return true;
+ }
+
+ if (x11_util::IsWindowVisible(window)) {
+ // The window isn't visible, keep iterating.
+ return false;
+ }
+
+ gfx::Rect rect;
+ if (x11_util::GetWindowRect(window, &rect) && rect.Contains(screen_loc_)) {
+ // At this point we haven't found our target window, so this window is
+ // higher in the z-order than the target window. If this window contains
+ // the point, then we can stop the search now because this window is
+ // obscuring the target window at this point.
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ TopMostFinder(XID window,
+ const gfx::Point& screen_loc,
+ const std::set<GtkWidget*>& ignore)
+ : BaseWindowFinder(ignore),
+ target_(window),
+ screen_loc_(screen_loc),
+ is_top_most_(false) {
+ XID root = x11_util::GetX11RootWindow();
+ x11_util::EnumerateChildWindows(root, this);
+ }
+
+ // The window we're looking for.
+ XID target_;
+
+ // Location of window to find.
+ gfx::Point screen_loc_;
+
+ // Is target_ the top most window? This is initially false but set to true
+ // in ShouldStopIterating if target_ is passed in.
+ bool is_top_most_;
+
+ DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// LocalProcessWindowFinder
+//
+// Helper class to determine if a particular point of a window from our process
+// is not obscured by another window.
+class LocalProcessWindowFinder : public BaseWindowFinder {
+ public:
+ // Returns the XID from our process at screen_loc that is not obscured by
+ // another window. Returns 0 otherwise.
+ static XID GetProcessWindowAtPoint(const gfx::Point& screen_loc,
+ const std::set<GtkWidget*>& ignore) {
+ LocalProcessWindowFinder finder(screen_loc, ignore);
+ if (finder.result_ &&
+ TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
+ ignore)) {
+ return finder.result_;
+ }
+ return 0;
+ }
+
+ protected:
+ virtual bool ShouldStopIterating(XID window) {
+ if (BaseWindowFinder::ShouldStopIterating(window))
+ return true;
+
+ // Check if this window is in our process.
+ if (!BrowserWindowGtk::GetBrowserWindowForXID(window))
+ return false;
+
+ if (!x11_util::IsWindowVisible(window))
+ return false;
+
+ gfx::Rect rect;
+ if (x11_util::GetWindowRect(window, &rect) && rect.Contains(screen_loc_)) {
+ result_ = window;
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ LocalProcessWindowFinder(const gfx::Point& screen_loc,
+ const std::set<GtkWidget*>& ignore)
+ : BaseWindowFinder(ignore),
+ screen_loc_(screen_loc),
+ result_(0) {
+ XID root = x11_util::GetX11RootWindow();
+ x11_util::EnumerateChildWindows(root, this);
+ }
+
+ // Position of the mouse.
+ gfx::Point screen_loc_;
+
+ // The resulting window. This is initially null but set to true in
+ // ShouldStopIterating if an appropriate window is found.
+ XID result_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
+};
+
+DockInfo::Factory* DockInfo::factory_ = NULL;
// static
DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
@@ -21,29 +185,16 @@ DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point,
return DockInfo();
}
+// static
GtkWindow* DockInfo::GetLocalProcessWindowAtPoint(
const gfx::Point& screen_point,
const std::set<GtkWidget*>& ignore) {
if (factory_)
return factory_->GetLocalProcessWindowAtPoint(screen_point, ignore);
- // Iterate over the browserlist to find the window at the specified point.
- // This is technically not correct as it doesn't take into account other
- // windows that may be on top of a browser window at the same point, but is
- // good enough for now.
- for (BrowserList::const_iterator i = BrowserList::begin();
- i != BrowserList::end(); ++i) {
- Browser* browser = *i;
- GtkWindow* window = browser->window()->GetNativeHandle();
- if (ignore.count(GTK_WIDGET(window)) == 0) {
- int x, y, w, h;
- gtk_window_get_position(window, &x, &y);
- gtk_window_get_size(window, &w, &h);
- if (gfx::Rect(x, y, w, h).Contains(screen_point))
- return window;
- }
- }
- return NULL;
+ XID xid =
+ LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
+ return BrowserWindowGtk::GetBrowserWindowForXID(xid);
}
bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const {
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 8cbf438..5c090d6 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -46,6 +46,8 @@ const int kLoadingAnimationFrameTimeMs = 30;
const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);
+const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__";
+
gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event,
BrowserWindowGtk* browser_win) {
gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height);
@@ -273,6 +275,8 @@ gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event, Browser* browser) {
} // namespace
+std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_;
+
// TODO(estade): Break up this constructor into helper functions to improve
// readability.
BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
@@ -283,7 +287,6 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
SetWindowIcon();
SetGeometryHints();
- g_object_set_data(G_OBJECT(window_), "browser_window_gtk", this);
g_signal_connect(window_, "delete-event",
G_CALLBACK(MainWindowDeleteEvent), this);
g_signal_connect(window_, "destroy",
@@ -292,12 +295,17 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
G_CALLBACK(MainWindowConfigured), this);
g_signal_connect(window_, "window-state-event",
G_CALLBACK(MainWindowStateChanged), this);
+ g_signal_connect(window_, "map",
+ G_CALLBACK(MainWindowMapped), this);
+ g_signal_connect(window_, "unmap",
+ G_CALLBACK(MainWindowUnMapped), this);
g_signal_connect(window_, "key-press-event",
G_CALLBACK(OnKeyPress), browser_.get());
g_signal_connect(window_, "button-press-event",
G_CALLBACK(OnButtonPressEvent), browser_.get());
g_signal_connect(window_, "focus-in-event",
G_CALLBACK(OnFocusIn), browser_.get());
+ g_object_set_data(G_OBJECT(window_), kBrowserWindowKey, this);
ConnectAccelerators();
bounds_ = GetInitialWindowBounds(window_);
@@ -741,6 +749,22 @@ void BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) {
gtk_box_reorder_child(GTK_BOX(render_area_vbox_), findbar->widget(), 0);
}
+// static
+BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow(
+ gfx::NativeWindow window) {
+ if (window) {
+ return static_cast<BrowserWindowGtk*>(
+ g_object_get_data(G_OBJECT(window), kBrowserWindowKey));
+ }
+
+ return NULL;
+}
+
+// static
+GtkWindow* BrowserWindowGtk::GetBrowserWindowForXID(XID xid) {
+ return BrowserWindowGtk::xid_map_.find(xid)->second;
+}
+
void BrowserWindowGtk::SetGeometryHints() {
// Allow the user to resize us arbitrarily small.
GdkGeometry geometry;
@@ -833,6 +857,23 @@ gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group,
return TRUE;
}
+// static
+void BrowserWindowGtk::MainWindowMapped(GtkWidget* widget,
+ BrowserWindowGtk* window) {
+ // Map the X Window ID of the window to our window.
+ XID xid = x11_util::GetX11WindowFromGtkWidget(widget);
+ BrowserWindowGtk::xid_map_.insert(
+ std::pair<XID, GtkWindow*>(xid, GTK_WINDOW(widget)));
+}
+
+// static
+void BrowserWindowGtk::MainWindowUnMapped(GtkWidget* widget,
+ BrowserWindowGtk* window) {
+ // Unmap the X Window ID.
+ XID xid = x11_util::GetX11WindowFromGtkWidget(widget);
+ BrowserWindowGtk::xid_map_.erase(xid);
+}
+
void BrowserWindowGtk::ExecuteBrowserCommand(int id) {
if (browser_->command_updater()->IsCommandEnabled(id))
browser_->ExecuteCommand(id);
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index d2c0589..8e6dee5 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -7,12 +7,15 @@
#include <gtk/gtk.h>
+#include <map>
+
#include "base/gfx/rect.h"
#include "base/scoped_ptr.h"
#include "base/timer.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/notification_registrar.h"
+#include "chrome/common/x11_util.h"
class BookmarkBarGtk;
class BrowserToolbarGtk;
@@ -94,6 +97,9 @@ class BrowserWindowGtk : public BrowserWindow,
bool user_gesture);
virtual void TabStripEmpty();
+ // Accessor for the tab strip.
+ TabStripGtk* tabstrip() const { return tabstrip_.get(); }
+
void MaybeShowBookmarkBar(TabContents* contents);
void UpdateUIForContents(TabContents* contents);
@@ -109,6 +115,14 @@ class BrowserWindowGtk : public BrowserWindow,
// Add the find bar widget to the window hierarchy.
void AddFindBar(FindBarGtk* findbar);
+ // Returns the BrowserWindowGtk registered with |window|.
+ static BrowserWindowGtk* GetBrowserWindowForNativeWindow(
+ gfx::NativeWindow window);
+
+ // Retrieves the GtkWindow associated with |xid|, which is the X Window
+ // ID of the top-level X window of this object.
+ static GtkWindow* GetBrowserWindowForXID(XID xid);
+
protected:
virtual void DestroyBrowser();
// Top level window.
@@ -154,6 +168,10 @@ class BrowserWindowGtk : public BrowserWindow,
GdkModifierType modifier,
BrowserWindowGtk* browser_window);
+ // Maps and Unmaps the xid of |widget| to |window|.
+ static void MainWindowMapped(GtkWidget* widget, BrowserWindowGtk* window);
+ static void MainWindowUnMapped(GtkWidget* widget, BrowserWindowGtk* window);
+
// A small shim for browser_->ExecuteCommand.
void ExecuteBrowserCommand(int id);
@@ -205,6 +223,9 @@ class BrowserWindowGtk : public BrowserWindow,
// The timer used to update frames for the Loading Animation.
base::RepeatingTimer<BrowserWindowGtk> loading_animation_timer_;
+ // A map which translates an X Window ID into its respective GtkWindow.
+ static std::map<XID, GtkWindow*> xid_map_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserWindowGtk);
};
diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc
index 96b4758..59c69ce 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc
+++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h"
#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_window.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/tabs/dragged_tab_gtk.h"
#include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
#include "chrome/browser/tabs/tab_strip_model.h"
@@ -75,6 +75,13 @@ bool DraggedTabControllerGtk::EndDrag(bool canceled) {
return EndDragImpl(canceled ? CANCELED : NORMAL);
}
+TabGtk* DraggedTabControllerGtk::GetDragSourceTabForContents(
+ TabContents* contents) const {
+ if (attached_tabstrip_ == source_tabstrip_)
+ return contents == dragged_contents_ ? source_tab_ : NULL;
+ return NULL;
+}
+
bool DraggedTabControllerGtk::IsDragSourceTab(TabGtk* tab) const {
return source_tab_ == tab;
}
@@ -266,8 +273,22 @@ void DraggedTabControllerGtk::MoveTab(const gfx::Point& screen_point) {
TabStripGtk* DraggedTabControllerGtk::GetTabStripForPoint(
const gfx::Point& screen_point) {
- // TODO(jhawkins): Actually get the correct tabstrip under |screen_point|.
- return GetTabStripIfItContains(source_tabstrip_, screen_point);
+ GtkWidget* dragged_window = dragged_tab_->widget();
+ dock_windows_.insert(dragged_window);
+ gfx::NativeWindow local_window =
+ DockInfo::GetLocalProcessWindowAtPoint(screen_point, dock_windows_);
+ dock_windows_.erase(dragged_window);
+ if (!local_window)
+ return NULL;
+
+ BrowserWindowGtk* browser =
+ BrowserWindowGtk::GetBrowserWindowForNativeWindow(local_window);
+ if (!browser)
+ return NULL;
+
+ TabStripGtk* other_tabstrip = browser->tabstrip();
+ // TODO(jhawkins): Make sure the tabstrips are compatible.
+ return GetTabStripIfItContains(other_tabstrip, screen_point);
}
TabStripGtk* DraggedTabControllerGtk::GetTabStripIfItContains(
diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h
index 08d656f..87ef243 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h
+++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h
@@ -7,11 +7,14 @@
#include <gtk/gtk.h>
+#include <set>
+
#include "base/scoped_ptr.h"
#include "base/timer.h"
#include "chrome/browser/dock_info.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/common/notification_registrar.h"
+#include "chrome/common/x11_util.h"
class DraggedTabGtk;
class TabGtk;
@@ -39,6 +42,11 @@ class DraggedTabControllerGtk : public NotificationObserver,
// begun. Returns whether the tab has been destroyed.
bool EndDrag(bool canceled);
+ // Retrieve the source tab if the TabContents specified matches the one being
+ // dragged by this controller, or NULL if the specified TabContents is not
+ // the same as the one being dragged.
+ TabGtk* GetDragSourceTabForContents(TabContents* contents) const;
+
// Returns true if the specified tab matches the tab being dragged.
bool IsDragSourceTab(TabGtk* tab) const;
@@ -225,6 +233,9 @@ class DraggedTabControllerGtk : public NotificationObserver,
// DockInfo for the tabstrip.
DockInfo dock_info_;
+ typedef std::set<GtkWidget*> DockWindows;
+ DockWindows dock_windows_;
+
// Timer used to bring the window under the cursor to front. If the user
// stops moving the mouse for a brief time over a browser window, it is
// brought to front.
diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.h b/chrome/browser/gtk/tabs/dragged_tab_gtk.h
index 3ff4231..fab68e1 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_gtk.h
+++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.h
@@ -49,6 +49,8 @@ class DraggedTabGtk : public AnimationDelegate {
// to determine where to place the tab in the attached tabstrip.
gfx::Size attached_tab_size() const { return attached_tab_size_; }
+ GtkWidget* widget() const { return container_; }
+
private:
// Overridden from AnimationDelegate:
virtual void AnimationProgressed(const Animation* animation);
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 00f3fbf..57891f7 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -592,20 +592,48 @@ void TabStripGtk::TabInsertedAt(TabContents* contents,
if (active_animation_.get())
active_animation_->Stop();
- TabGtk* tab = new TabGtk(this);
+ bool contains_tab = false;
+ TabGtk* tab = NULL;
+ // First see if this Tab is one that was dragged out of this TabStrip and is
+ // now being dragged back in. In this case, the DraggedTabController actually
+ // has the Tab already constructed and we can just insert it into our list
+ // again.
+ if (IsDragSessionActive()) {
+ tab = drag_controller_->GetDragSourceTabForContents(contents);
+ if (tab) {
+ // If the Tab was detached, it would have been animated closed but not
+ // removed, so we need to reset this property.
+ tab->set_closing(false);
+ tab->ValidateLoadingAnimation(TabRendererGtk::ANIMATION_NONE);
+ tab->SetVisible(true);
+ }
+
+ // See if we're already in the list. We don't want to add ourselves twice.
+ std::vector<TabData>::const_iterator iter = tab_data_.begin();
+ for (; iter != tab_data_.end() && !contains_tab; ++iter) {
+ if (iter->tab == tab)
+ contains_tab = true;
+ }
+ }
+
+ if (!tab)
+ tab = new TabGtk(this);
// Only insert if we're not already in the list.
- if (index == TabStripModel::kNoTab) {
- TabData d = { tab, gfx::Rect() };
- tab_data_.push_back(d);
- tab->UpdateData(contents, false);
- } else {
- TabData d = { tab, gfx::Rect() };
- tab_data_.insert(tab_data_.begin() + index, d);
- tab->UpdateData(contents, false);
+ if (!contains_tab) {
+ if (index == TabStripModel::kNoTab) {
+ TabData d = { tab, gfx::Rect() };
+ tab_data_.push_back(d);
+ tab->UpdateData(contents, false);
+ } else {
+ TabData d = { tab, gfx::Rect() };
+ tab_data_.insert(tab_data_.begin() + index, d);
+ tab->UpdateData(contents, false);
+ }
}
- gtk_fixed_put(GTK_FIXED(tabstrip_.get()), tab->widget(), 0, 0);
+ if (gtk_widget_get_parent(tab->widget()) != tabstrip_.get())
+ gtk_fixed_put(GTK_FIXED(tabstrip_.get()), tab->widget(), 0, 0);
// Don't animate the first tab; it looks weird.
if (GetTabCount() > 1) {
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index d6a537a..174b7e7 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -255,8 +255,8 @@ void TabContentsViewGtk::HandleKeyboardEvent(
return;
}
- BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>(
- g_object_get_data(G_OBJECT(window), "browser_window_gtk"));
+ BrowserWindowGtk* browser_window =
+ BrowserWindowGtk::GetBrowserWindowForNativeWindow(window);
DCHECK(browser_window);
browser_window->HandleAccelerator(event.os_event->keyval,
static_cast<GdkModifierType>(event.os_event->state));
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index a82e7dc..552dd5b 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1795,11 +1795,6 @@
['exclude', '^browser/bookmarks/bookmark_context_menu_gtk.cc'],
],
}],
- ['toolkit_views==0',{
- 'sources/': [
- ['exclude', '^browser/dock_info_gtk.cc'],
- ],
- }],
],
# Exclude files that should be excluded for all non-Windows platforms.
'sources!': [
diff --git a/chrome/common/x11_util.cc b/chrome/common/x11_util.cc
index 5371573..b1a24bf 100644
--- a/chrome/common/x11_util.cc
+++ b/chrome/common/x11_util.cc
@@ -6,9 +6,7 @@
// ported from XCB since we can't use XCB on Ubuntu while its 32-bit support
// remains woefully incomplete.
-#include "base/thread.h"
#include "chrome/common/x11_util.h"
-#include "chrome/common/x11_util_internal.h"
#include <string.h>
@@ -21,6 +19,8 @@
#include "base/logging.h"
#include "base/gfx/size.h"
+#include "base/thread.h"
+#include "chrome/common/x11_util_internal.h"
namespace x11_util {
@@ -137,6 +137,44 @@ int BitsPerPixelForPixmapDepth(Display* dpy, int depth) {
return bits_per_pixel;
}
+bool IsWindowVisible(XID window) {
+ XWindowAttributes win_attributes;
+ XGetWindowAttributes(GetXDisplay(), window, &win_attributes);
+ return (win_attributes.map_state == IsViewable);
+}
+
+bool GetWindowRect(XID window, gfx::Rect* rect) {
+ Window root_window;
+ int x, y;
+ unsigned int width, height;
+ unsigned int border_width, depth;
+
+ if (!XGetGeometry(GetXDisplay(), window, &root_window, &x, &y,
+ &width, &height, &border_width, &depth))
+ return false;
+
+ *rect = gfx::Rect(x, y, width, height);
+ return true;
+}
+
+bool EnumerateChildWindows(XID root, EnumerateWindowsDelegate* delegate) {
+ XID parent;
+ XID* children;
+ unsigned int num_children;
+ int status = XQueryTree(GetXDisplay(), root, &root, &parent,
+ &children, &num_children);
+ if (status == 0)
+ return false;
+
+ for (unsigned int i = 0; i < num_children; i++) {
+ if (delegate->ShouldStopIterating(children[i]))
+ break;
+ }
+
+ XFree(children);
+ return true;
+}
+
XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) {
static XRenderPictFormat* pictformat = NULL;
if (pictformat)
diff --git a/chrome/common/x11_util.h b/chrome/common/x11_util.h
index dddd40c..d177800 100644
--- a/chrome/common/x11_util.h
+++ b/chrome/common/x11_util.h
@@ -11,6 +11,9 @@
// we use a void* for Visual*). The Xlib headers are highly polluting so we try
// hard to limit their spread into the rest of the code.
+#include "base/gfx/rect.h"
+#include "base/task.h"
+
typedef struct _GdkDrawable GdkWindow;
typedef struct _GtkWidget GtkWidget;
typedef unsigned long XID;
@@ -45,13 +48,29 @@ int GetDefaultScreen(Display* display);
// Get the X window id for the default root window
XID GetX11RootWindow();
// Get the X window id for the given GTK widget.
-XID GetX11WindowFromGtkWidget(GtkWidget*);
-XID GetX11WindowFromGdkWindow(GdkWindow*);
+XID GetX11WindowFromGtkWidget(GtkWidget* widget);
+XID GetX11WindowFromGdkWindow(GdkWindow* window);
// Get a Visual from the given widget. Since we don't include the Xlib
// headers, this is returned as a void*.
-void* GetVisualFromGtkWidget(GtkWidget*);
+void* GetVisualFromGtkWidget(GtkWidget* widget);
// Return the number of bits-per-pixel for a pixmap of the given depth
-int BitsPerPixelForPixmapDepth(Display*, int depth);
+int BitsPerPixelForPixmapDepth(Display* display, int depth);
+// Returns true if |window| is visible.
+bool IsWindowVisible(XID window);
+// Returns the bounds of |window|.
+bool GetWindowRect(XID window, gfx::Rect* rect);
+
+// Implementers of this interface receive a notification for every X window of
+// the main display.
+class EnumerateWindowsDelegate {
+ public:
+ // |xid| is the X Window ID of the enumerated window. Return true to stop
+ // further iteration.
+ virtual bool ShouldStopIterating(XID xid) = 0;
+};
+
+// Enumerates the child windows of |root|.
+bool EnumerateChildWindows(XID root, EnumerateWindowsDelegate* delegate);
// Return a handle to a server side pixmap. |shared_memory_key| is a SysV
// IPC key. The shared memory region must contain 32-bit pixels.