diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-26 01:08:54 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-26 01:08:54 +0000 |
commit | 8cbb4a6929bfbe03318271cd42489ce94a8a19f7 (patch) | |
tree | 144c94403c1daa7f00345df93b4bddd928bc0028 /ui | |
parent | 6153992ea99877d472dd29b77efc9db88ec8e539 (diff) | |
download | chromium_src-8cbb4a6929bfbe03318271cd42489ce94a8a19f7.zip chromium_src-8cbb4a6929bfbe03318271cd42489ce94a8a19f7.tar.gz chromium_src-8cbb4a6929bfbe03318271cd42489ce94a8a19f7.tar.bz2 |
linux_aura: Fix cursors and popup menu location
- Cursors now use sadrul's modified CursorLoader.
- We query the desktop environment for work area size. This makes menus
positioned in the correct place.
BUG=146077
Review URL: https://chromiumcodereview.appspot.com/10985029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158708 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/cursor/cursor_loader_x11.h | 3 | ||||
-rw-r--r-- | ui/views/widget/desktop_root_window_host_linux.cc | 65 | ||||
-rw-r--r-- | ui/views/widget/desktop_root_window_host_linux.h | 26 | ||||
-rw-r--r-- | ui/views/widget/widget.h | 2 |
4 files changed, 85 insertions, 11 deletions
diff --git a/ui/base/cursor/cursor_loader_x11.h b/ui/base/cursor/cursor_loader_x11.h index 32f0e1a..d645512 100644 --- a/ui/base/cursor/cursor_loader_x11.h +++ b/ui/base/cursor/cursor_loader_x11.h @@ -11,10 +11,11 @@ #include "base/compiler_specific.h" #include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor_loader.h" +#include "ui/base/ui_export.h" namespace ui { -class CursorLoaderX11 : public CursorLoader { +class UI_EXPORT CursorLoaderX11 : public CursorLoader { public: CursorLoaderX11(); virtual ~CursorLoaderX11(); diff --git a/ui/views/widget/desktop_root_window_host_linux.cc b/ui/views/widget/desktop_root_window_host_linux.cc index fcc8c71..051ddf0 100644 --- a/ui/views/widget/desktop_root_window_host_linux.cc +++ b/ui/views/widget/desktop_root_window_host_linux.cc @@ -65,6 +65,9 @@ DesktopRootWindowHostLinux::DesktopRootWindowHostLinux( window_mapped_(false), focus_when_shown_(false), has_capture_(false), + cursor_loader_(), + current_cursor_(ui::kCursorNull), + cursor_shown_(true), native_widget_delegate_(native_widget_delegate) { } @@ -111,8 +114,7 @@ void DesktopRootWindowHostLinux::InitX11Window( XSelectInput(xdisplay_, xwindow_, event_mask); XFlush(xdisplay_); - // TODO(erg): Something about an invisible cursor here? Don't think I need - // it, but this is where it was. + invisible_cursor_ = ui::CreateInvisibleCursor(); // TODO(erg): We currently only request window deletion events. We also // should listen for activation events and anything else that GTK+ listens @@ -175,6 +177,14 @@ void DesktopRootWindowHostLinux::InitRootWindow( aura::client::SetDispatcherClient(root_window_.get(), dispatcher_client_.get()); + // The cursor client is a curious thing; it proxies some, but not all, calls + // to our SetCursor() method. We require all calls to go through a route that + // uses a CursorLoader, which includes all the ones in views:: internal. + // + // TODO(erg): This is a code smell. I suspect that I'm working around the + // CursorClient's interface being plain wrong. + aura::client::SetCursorClient(root_window_.get(), this); + // No event filter for aura::Env. Create CompoundEvnetFilter per RootWindow. root_window_event_filter_ = new aura::shared::CompoundEventFilter; // Pass ownership of the filter to the root_window. @@ -309,9 +319,14 @@ gfx::Rect DesktopRootWindowHostLinux::GetWindowBoundsInScreen() const { } gfx::Rect DesktopRootWindowHostLinux::GetClientAreaBoundsInScreen() const { - NOTIMPLEMENTED(); - // TODO(erg): This is wrong, but would require looking at the actual views - // hierarchy to do correctly. + // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its + // needed for View::ConvertPointToScreen() to work + // correctly. DesktopRootWindowHostWin::GetClientAreaBoundsInScreen() just + // asks windows what it thinks the client rect is. + // + // Attempts to calculate the rect by asking the NonClientFrameView what it + // thought its GetBoundsForClientView() were broke combobox drop down + // placement. return bounds_; } @@ -322,7 +337,14 @@ gfx::Rect DesktopRootWindowHostLinux::GetRestoredBounds() const { } gfx::Rect DesktopRootWindowHostLinux::GetWorkAreaBoundsInScreen() const { - // TODO(erg): + std::vector<int> value; + if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && + value.size() >= 4) { + return gfx::Rect(value[0], value[1], value[2], value[3]); + } + + // TODO(erg): As a fallback, we should return the bounds for the current + // monitor. However, that's pretty difficult and requires futzing with XRR. NOTIMPLEMENTED(); return gfx::Rect(); } @@ -373,6 +395,10 @@ bool DesktopRootWindowHostLinux::IsMinimized() const { return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); } +void DesktopRootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { + XDefineCursor(xdisplay_, xwindow_, cursor.platform()); +} + bool DesktopRootWindowHostLinux::HasCapture() const { return has_capture_; } @@ -565,11 +591,21 @@ void DesktopRootWindowHostLinux::ReleaseCapture() { } void DesktopRootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { - NOTIMPLEMENTED(); + cursor_loader_.SetPlatformCursor(&cursor); + + if (cursor == current_cursor_) + return; + current_cursor_ = cursor; + + if (cursor_shown_) + SetCursorInternal(cursor); } void DesktopRootWindowHostLinux::ShowCursor(bool show) { - NOTIMPLEMENTED(); + if (show == cursor_shown_) + return; + cursor_shown_ = show; + SetCursorInternal(show ? current_cursor_ : invisible_cursor_); } bool DesktopRootWindowHostLinux::QueryMouseLocation( @@ -663,6 +699,19 @@ void DesktopRootWindowHostLinux::PrepareForShutdown() { } //////////////////////////////////////////////////////////////////////////////// +// DesktopRootWindowHostLinux, aura::CursorClient implementation: + +bool DesktopRootWindowHostLinux::IsCursorVisible() const { + return cursor_shown_; +} + +void DesktopRootWindowHostLinux::SetDeviceScaleFactor( + float device_scale_factor) { + cursor_loader_.UnloadAll(); + cursor_loader_.set_device_scale_factor(device_scale_factor); +} + +//////////////////////////////////////////////////////////////////////////////// // DesktopRootWindowHostLinux, MessageLoop::Dispatcher implementation: bool DesktopRootWindowHostLinux::Dispatch(const base::NativeEvent& event) { diff --git a/ui/views/widget/desktop_root_window_host_linux.h b/ui/views/widget/desktop_root_window_host_linux.h index b34c385..81f3020 100644 --- a/ui/views/widget/desktop_root_window_host_linux.h +++ b/ui/views/widget/desktop_root_window_host_linux.h @@ -11,8 +11,10 @@ #undef RootWindow #include "base/basictypes.h" +#include "ui/aura/client/cursor_client.h" #include "ui/aura/root_window_host.h" #include "ui/gfx/rect.h" +#include "ui/base/cursor/cursor_loader_x11.h" #include "ui/base/x/x11_atom_cache.h" #include "ui/views/widget/desktop_root_window_host.h" @@ -32,6 +34,7 @@ class X11WindowEventFilter; class DesktopRootWindowHostLinux : public DesktopRootWindowHost, public aura::RootWindowHost, + public aura::client::CursorClient, public MessageLoop::Dispatcher { public: DesktopRootWindowHostLinux( @@ -60,6 +63,10 @@ class DesktopRootWindowHostLinux : public DesktopRootWindowHost, // Checks if the window manager has set a specific state. bool HasWMSpecProperty(const char* property) const; + // Sets the cursor on |xwindow_| to |cursor|. Does not check or update + // |current_cursor_|. + void SetCursorInternal(gfx::NativeCursor cursor); + // Overridden from DesktopRootWindowHost: virtual void Init(aura::Window* content_window, const Widget::InitParams& params) OVERRIDE; @@ -137,7 +144,12 @@ class DesktopRootWindowHostLinux : public DesktopRootWindowHost, virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE; virtual void PrepareForShutdown() OVERRIDE; - // Overridden from Dispatcher overrides: + // Overridden from aura::CursorClient: + // Note: other methods are just set on aura::RootWindowHost: + virtual bool IsCursorVisible() const OVERRIDE; + virtual void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + + // Overridden from Dispatcher: virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE; // X11 things @@ -171,6 +183,18 @@ class DesktopRootWindowHostLinux : public DesktopRootWindowHost, scoped_ptr<aura::DesktopActivationClient> activation_client_; scoped_ptr<aura::DesktopDispatcherClient> dispatcher_client_; + // Translates custom bitmaps provided by the webpage into X11 cursors. + ui::CursorLoaderX11 cursor_loader_; + + // Current Aura cursor. + gfx::NativeCursor current_cursor_; + + // Is the cursor currently shown? + bool cursor_shown_; + + // The invisible cursor. + ::Cursor invisible_cursor_; + // Toplevel event filter which dispatches to other event filters. aura::shared::CompoundEventFilter* root_window_event_filter_; diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index f9d5b67..0379cf5 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h @@ -604,7 +604,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, // with it. TYPE_CONTROL and TYPE_TOOLTIP is not considered top level. bool is_top_level() const { return is_top_level_; } - // Returns the work are bounds of the screen the Widget belongs to. + // Returns the work area bounds of the screen the Widget belongs to. gfx::Rect GetWorkAreaBoundsInScreen() const; // Notification that our owner is closing. |