diff options
-rw-r--r-- | chrome/browser/fullscreen_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/screensaver_window_finder_gtk.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/aura/tabs/dock_info_aura.cc | 38 | ||||
-rw-r--r-- | chrome/browser/ui/aura/tabs/dock_info_aurax11.cc | 220 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/gtk_util.cc | 19 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/gtk_util.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/tabs/dock_info_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 7 | ||||
-rw-r--r-- | ui/aura/root_window.h | 2 | ||||
-rw-r--r-- | ui/base/x/x11_util.cc | 19 | ||||
-rw-r--r-- | ui/base/x/x11_util.h | 3 | ||||
-rw-r--r-- | ui/views/widget/desktop_native_widget_helper_aura.cc | 13 | ||||
-rw-r--r-- | ui/views/widget/desktop_native_widget_helper_aura.h | 5 |
14 files changed, 276 insertions, 68 deletions
diff --git a/chrome/browser/fullscreen_gtk.cc b/chrome/browser/fullscreen_gtk.cc index da69642..c9d3a70 100644 --- a/chrome/browser/fullscreen_gtk.cc +++ b/chrome/browser/fullscreen_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,7 +17,7 @@ namespace { -// TODO (jianli): Merge with gtk_util::EnumerateTopLevelWindows. +// TODO (jianli): Merge with ui::EnumerateTopLevelWindows. void EnumerateAllChildWindows(ui::EnumerateWindowsDelegate* delegate, XID window) { std::vector<XID> windows; diff --git a/chrome/browser/screensaver_window_finder_gtk.cc b/chrome/browser/screensaver_window_finder_gtk.cc index a94f323..4707514 100644 --- a/chrome/browser/screensaver_window_finder_gtk.cc +++ b/chrome/browser/screensaver_window_finder_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,6 @@ #include <gdk/gdkx.h> #include "base/basictypes.h" -#include "chrome/browser/ui/gtk/gtk_util.h" #include "ui/base/x/x11_util.h" @@ -19,7 +18,7 @@ ScreensaverWindowFinder::ScreensaverWindowFinder() bool ScreensaverWindowFinder::ScreensaverWindowExists() { gdk_error_trap_push(); ScreensaverWindowFinder finder; - gtk_util::EnumerateTopLevelWindows(&finder); + ui::EnumerateTopLevelWindows(&finder); bool got_error = gdk_error_trap_pop(); return finder.exists_ && !got_error; } diff --git a/chrome/browser/ui/aura/tabs/dock_info_aura.cc b/chrome/browser/ui/aura/tabs/dock_info_aura.cc deleted file mode 100644 index bf500de..0000000 --- a/chrome/browser/ui/aura/tabs/dock_info_aura.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/tabs/dock_info.h" - -#include "ui/aura/window.h" - -#if !defined(USE_ASH) - -// static -DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point, - const std::set<gfx::NativeView>& ignore) { - // TODO(beng): - NOTIMPLEMENTED(); - return DockInfo(); -} - -// static -gfx::NativeView DockInfo::GetLocalProcessWindowAtPoint( - const gfx::Point& screen_point, - const std::set<gfx::NativeView>& ignore) { - NOTIMPLEMENTED(); - return NULL; -} - -bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const { - if (!window()) - return false; - *bounds = window_->bounds(); - return true; -} - -void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const { - window_->SetBounds(bounds); -} - -#endif diff --git a/chrome/browser/ui/aura/tabs/dock_info_aurax11.cc b/chrome/browser/ui/aura/tabs/dock_info_aurax11.cc new file mode 100644 index 0000000..b32822c --- /dev/null +++ b/chrome/browser/ui/aura/tabs/dock_info_aurax11.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/tabs/dock_info.h" + +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/base/x/x11_util.h" +#include "ui/views/widget/desktop_native_widget_helper_aura.h" + +#if !defined(USE_ASH) + +namespace { + +//////////////////////////////////////////////////////////////////////////////// +// BaseWindowFinder +// +// Base class used to locate a window. A subclass need only override +// ShouldStopIterating to determine when iteration should stop. +class BaseWindowFinder : public ui::EnumerateWindowsDelegate { + public: + explicit BaseWindowFinder(const std::set<aura::Window*>& ignore) { + std::set<aura::Window*>::iterator iter; + for (iter = ignore.begin(); iter != ignore.end(); iter++) { + XID xid = (*iter)->GetRootWindow()->GetAcceleratedWidget(); + ignore_.insert(xid); + } + } + + virtual ~BaseWindowFinder() {} + + protected: + // Returns true if |window| is in the ignore list. + bool ShouldIgnoreWindow(XID window) { + return (ignore_.find(window) != ignore_.end()); + } + + // Returns true if iteration should stop, false otherwise. + virtual bool ShouldStopIterating(XID window) { + return false; + } + + 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<aura::Window*>& ignore) { + TopMostFinder finder(window, screen_loc, ignore); + return finder.is_top_most_; + } + + protected: + virtual bool ShouldStopIterating(XID window) { + if (BaseWindowFinder::ShouldIgnoreWindow(window)) + return false; + + if (window == target_) { + // Window is topmost, stop iterating. + is_top_most_ = true; + return true; + } + + if (!ui::IsWindowVisible(window)) { + // The window isn't visible, keep iterating. + return false; + } + + gfx::Rect rect; + if (ui::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<aura::Window*>& ignore) + : BaseWindowFinder(ignore), + target_(window), + screen_loc_(screen_loc), + is_top_most_(false) { + ui::EnumerateTopLevelWindows(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<aura::Window*>& 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::ShouldIgnoreWindow(window)) + return false; + + // Check if this window is in our process. + if (!aura::RootWindow::GetForAcceleratedWidget(window)) + return false; + + if (!ui::IsWindowVisible(window)) + return false; + + gfx::Rect rect; + if (ui::GetWindowRect(window, &rect) && rect.Contains(screen_loc_)) { + result_ = window; + return true; + } + + return false; + } + + private: + LocalProcessWindowFinder(const gfx::Point& screen_loc, + const std::set<aura::Window*>& ignore) + : BaseWindowFinder(ignore), + screen_loc_(screen_loc), + result_(0) { + ui::EnumerateTopLevelWindows(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); +}; + +} // namespace + +// static +DockInfo DockInfo::GetDockInfoAtPoint(const gfx::Point& screen_point, + const std::set<gfx::NativeView>& ignore) { + // TODO(beng): + NOTIMPLEMENTED(); + return DockInfo(); +} + +// static +gfx::NativeView DockInfo::GetLocalProcessWindowAtPoint( + const gfx::Point& screen_point, + const std::set<gfx::NativeView>& ignore) { + // The X11 server is the canonical state of what the window stacking order + // is. + XID xid = + LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore); + aura::RootWindow* root_window = + aura::RootWindow::GetForAcceleratedWidget(xid); + + if (!root_window) + return NULL; + + // We now have the aura::RootWindow, but most of views isn't interested in + // that; instead it wants the aura::Window that is contained by the + // RootWindow. + return views::DesktopNativeWidgetHelperAura::GetViewsWindowForRootWindow( + root_window); +} + +bool DockInfo::GetWindowBounds(gfx::Rect* bounds) const { + if (!window()) + return false; + *bounds = window_->bounds(); + return true; +} + +void DockInfo::SizeOtherWindowTo(const gfx::Rect& bounds) const { + window_->SetBounds(bounds); +} + +#endif diff --git a/chrome/browser/ui/gtk/gtk_util.cc b/chrome/browser/ui/gtk/gtk_util.cc index c287149..4140b515 100644 --- a/chrome/browser/ui/gtk/gtk_util.cc +++ b/chrome/browser/ui/gtk/gtk_util.cc @@ -517,25 +517,6 @@ GtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, return centering_vbox; } -void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate) { - std::vector<XID> stack; - if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) { - // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back - // to old school enumeration of all X windows. Some WMs parent 'top-level' - // windows in unnamed actual top-level windows (ion WM), so extend the - // search depth to all children of top-level windows. - const int kMaxSearchDepth = 1; - ui::EnumerateAllWindows(delegate, kMaxSearchDepth); - return; - } - - std::vector<XID>::iterator iter; - for (iter = stack.begin(); iter != stack.end(); iter++) { - if (delegate->ShouldStopIterating(*iter)) - return; - } -} - void SetButtonClickableByMouseButtons(GtkWidget* button, bool left, bool middle, bool right) { gint button_mask = 0; diff --git a/chrome/browser/ui/gtk/gtk_util.h b/chrome/browser/ui/gtk/gtk_util.h index 2820f47..f221200 100644 --- a/chrome/browser/ui/gtk/gtk_util.h +++ b/chrome/browser/ui/gtk/gtk_util.h @@ -113,9 +113,6 @@ void ConvertWidgetPointToScreen(GtkWidget* widget, gfx::Point* p); GtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, bool pack_at_end, int padding); -// Enumerates the top-level gdk windows of the current display. -void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate); - // Set that clicking the button with the given mouse buttons will cause a click // event. // NOTE: If you need to connect to the button-press-event or diff --git a/chrome/browser/ui/gtk/tabs/dock_info_gtk.cc b/chrome/browser/ui/gtk/tabs/dock_info_gtk.cc index a690dd7..e340330 100644 --- a/chrome/browser/ui/gtk/tabs/dock_info_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/dock_info_gtk.cc @@ -100,7 +100,7 @@ class TopMostFinder : public BaseWindowFinder { target_(window), screen_loc_(screen_loc), is_top_most_(false) { - gtk_util::EnumerateTopLevelWindows(this); + ui::EnumerateTopLevelWindows(this); } // The window we're looking for. @@ -163,7 +163,7 @@ class LocalProcessWindowFinder : public BaseWindowFinder { : BaseWindowFinder(ignore), screen_loc_(screen_loc), result_(0) { - gtk_util::EnumerateTopLevelWindows(this); + ui::EnumerateTopLevelWindows(this); } // Position of the mouse. diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 23e03e2..0d7a22e 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2337,7 +2337,7 @@ 'browser/ui/ash/tabs/dock_info_ash.cc', 'browser/ui/aura/chrome_browser_main_extra_parts_aura.cc', 'browser/ui/aura/chrome_browser_main_extra_parts_aura.h', - 'browser/ui/aura/tabs/dock_info_aura.cc', + 'browser/ui/aura/tabs/dock_info_aurax11.cc', 'browser/ui/auto_login_info_bar_delegate.cc', 'browser/ui/auto_login_info_bar_delegate.h', 'browser/ui/auto_login_prompter.cc', diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 6c6d6bb..d3c99d7 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -159,6 +159,13 @@ RootWindow::~RootWindow() { layer()->GetAnimator()->RemoveObserver(this); } +// static +RootWindow* RootWindow::GetForAcceleratedWidget( + gfx::AcceleratedWidget widget) { + RootWindowHost* host = RootWindowHost::GetForAcceleratedWidget(widget); + return host ? host->GetRootWindow() : NULL; +} + void RootWindow::Init() { compositor()->SetScaleAndSize(GetDeviceScaleFactorFromMonitor(this), host_->GetBounds().size()); diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index 2d13e76..4a9ac6a 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -84,6 +84,8 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, explicit RootWindow(const gfx::Rect& initial_bounds); virtual ~RootWindow(); + static RootWindow* GetForAcceleratedWidget(gfx::AcceleratedWidget widget); + static void set_hide_host_cursor(bool hide) { hide_host_cursor_ = hide; } diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index d0d0188..b058b2f 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc @@ -769,6 +769,25 @@ bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate, int max_depth) { return EnumerateChildren(delegate, root, max_depth, 0); } +void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate) { + std::vector<XID> stack; + if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) { + // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back + // to old school enumeration of all X windows. Some WMs parent 'top-level' + // windows in unnamed actual top-level windows (ion WM), so extend the + // search depth to all children of top-level windows. + const int kMaxSearchDepth = 1; + ui::EnumerateAllWindows(delegate, kMaxSearchDepth); + return; + } + + std::vector<XID>::iterator iter; + for (iter = stack.begin(); iter != stack.end(); iter++) { + if (delegate->ShouldStopIterating(*iter)) + return; + } +} + bool GetXWindowStack(Window window, std::vector<XID>* windows) { windows->clear(); diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h index a0ac398..f0ee270 100644 --- a/ui/base/x/x11_util.h +++ b/ui/base/x/x11_util.h @@ -188,6 +188,9 @@ class EnumerateWindowsDelegate { UI_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate, int max_depth); +// Enumerates the top-level windows of the current display. +UI_EXPORT void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate); + // Returns all children windows of a given window in top-to-bottom stacking // order. UI_EXPORT bool GetXWindowStack(XID window, std::vector<XID>* windows); diff --git a/ui/views/widget/desktop_native_widget_helper_aura.cc b/ui/views/widget/desktop_native_widget_helper_aura.cc index 9cc3531..5272acb 100644 --- a/ui/views/widget/desktop_native_widget_helper_aura.cc +++ b/ui/views/widget/desktop_native_widget_helper_aura.cc @@ -14,6 +14,7 @@ #include "ui/aura/shared/compound_event_filter.h" #include "ui/aura/shared/input_method_event_filter.h" #include "ui/aura/shared/root_window_capture_client.h" +#include "ui/aura/window_property.h" #include "ui/views/widget/native_widget_aura.h" #if defined(OS_WIN) @@ -23,8 +24,13 @@ #include "ui/views/widget/x11_window_event_filter.h" #endif +DECLARE_WINDOW_PROPERTY_TYPE(aura::Window*); + namespace views { +DEFINE_WINDOW_PROPERTY_KEY( + aura::Window*, kViewsWindowForRootWindow, NULL); + namespace { // Client that always offsets the passed in point by the RootHost's origin. @@ -85,6 +91,12 @@ DesktopNativeWidgetHelperAura::~DesktopNativeWidgetHelperAura() { } } +// static +aura::Window* DesktopNativeWidgetHelperAura::GetViewsWindowForRootWindow( + aura::RootWindow* root) { + return root ? root->GetProperty(kViewsWindowForRootWindow) : NULL; +} + void DesktopNativeWidgetHelperAura::PreInitialize( aura::Window* window, const Widget::InitParams& params) { @@ -115,6 +127,7 @@ void DesktopNativeWidgetHelperAura::PreInitialize( // cursor's shape and visibility. root_window_.reset(new aura::RootWindow(bounds)); + root_window_->SetProperty(kViewsWindowForRootWindow, window); root_window_->Init(); root_window_->set_focus_manager(new aura::FocusManager); diff --git a/ui/views/widget/desktop_native_widget_helper_aura.h b/ui/views/widget/desktop_native_widget_helper_aura.h index 2149c1b..91ac740 100644 --- a/ui/views/widget/desktop_native_widget_helper_aura.h +++ b/ui/views/widget/desktop_native_widget_helper_aura.h @@ -46,6 +46,11 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura explicit DesktopNativeWidgetHelperAura(NativeWidgetAura* widget); virtual ~DesktopNativeWidgetHelperAura(); + // In general, views/ does not care about the aura::RootWindow, even though + // at any join point with the native OS, we're going to be dealing in + // RootWindows. + static aura::Window* GetViewsWindowForRootWindow(aura::RootWindow* root); + // Overridden from aura::NativeWidgetHelperAura: virtual void PreInitialize(aura::Window* window, const Widget::InitParams& params) OVERRIDE; |