Chromium Code Reviews| Index: ui/aura/root_window_host_linux.cc |
| diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc |
| index aa528b9414a75ea3f03097e382dc27dbe444ab84..50708d3b22fed5a70de3fb00ca70f082b41a3a47 100644 |
| --- a/ui/aura/root_window_host_linux.cc |
| +++ b/ui/aura/root_window_host_linux.cc |
| @@ -6,6 +6,7 @@ |
| #include <X11/cursorfont.h> |
| #include <X11/extensions/XInput2.h> |
| +#include <X11/extensions/Xfixes.h> |
| #include <X11/extensions/Xrandr.h> |
| #include <algorithm> |
| @@ -16,7 +17,6 @@ |
| #include "ui/aura/env.h" |
| #include "ui/aura/event.h" |
| #include "ui/aura/monitor.h" |
| -#include "ui/aura/monitor_change_observer_x11.h" |
| #include "ui/aura/monitor_manager.h" |
| #include "ui/aura/root_window.h" |
| #include "ui/base/keycodes/keyboard_codes.h" |
| @@ -281,7 +281,8 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
| current_cursor_(aura::kCursorNull), |
| cursor_shown_(true), |
| bounds_(bounds), |
| - focus_when_shown_(false) { |
| + focus_when_shown_(false), |
| + pointer_barriers_(NULL) { |
| XSetWindowAttributes swa; |
| memset(&swa, 0, sizeof(swa)); |
| swa.background_pixmap = None; |
| @@ -295,7 +296,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
| CWBackPixmap, |
| &swa); |
| static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> |
| - RootWindowHostCreated(xwindow_, x_root_window_, this); |
| + WindowDispatcherCreated(xwindow_, this); |
| long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | |
| KeyPressMask | KeyReleaseMask | |
| @@ -323,7 +324,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
| RootWindowHostLinux::~RootWindowHostLinux() { |
| static_cast<DispatcherLinux*>(Env::GetInstance()->GetDispatcher())-> |
| - RootWindowHostDestroying(xwindow_, x_root_window_); |
| + WindowDispatcherDestroying(xwindow_); |
| XDestroyWindow(xdisplay_, xwindow_); |
| // Clears XCursorCache. |
| @@ -367,7 +368,14 @@ base::MessagePumpDispatcher::DispatchStatus RootWindowHostLinux::Dispatch( |
| case ConfigureNotify: { |
| DCHECK_EQ(xwindow_, xev->xconfigure.window); |
| DCHECK_EQ(xwindow_, xev->xconfigure.event); |
| - |
| + // Update barrier and mouse location when the root window has |
| + // moved/resized. |
| + if (pointer_barriers_.get()) { |
|
Daniel Erat
2012/03/23 16:49:16
It looks like you only update if we already had ba
oshima
2012/03/23 18:25:09
This is enabled for root window for primary monito
|
| + UnConfineCursor(); |
| + gfx::Point p = root_window_->last_mouse_location(); |
| + XWarpPointer(xdisplay_, None, xwindow_, 0, 0, 0, 0, p.x(), p.y()); |
| + ConfineCursorToRootWindow(); |
| + } |
| // It's possible that the X window may be resized by some other means than |
| // from within aura (e.g. the X window manager can change the size). Make |
| // sure the root window size is maintained properly. |
| @@ -480,12 +488,6 @@ base::MessagePumpDispatcher::DispatchStatus RootWindowHostLinux::Dispatch( |
| handled = root_window_->DispatchMouseEvent(&mouseev); |
| break; |
| } |
| - default: { |
| - // TODO(oshima): We probably should change DispatcherLinux so |
| - // that it can directly dispatch the event to montor change |
| - // observer. |
| - Env::GetInstance()->monitor_change_observer()->Dispatch(xev); |
| - } |
| } |
| return handled ? base::MessagePumpDispatcher::EVENT_PROCESSED : |
| base::MessagePumpDispatcher::EVENT_IGNORED; |
| @@ -578,19 +580,34 @@ gfx::Point RootWindowHostLinux::QueryMouseLocation() { |
| } |
| bool RootWindowHostLinux::ConfineCursorToRootWindow() { |
| - return XGrabPointer(xdisplay_, |
| - xwindow_, // grab_window |
| - False, // owner_events |
| - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, |
| - GrabModeAsync, |
| - GrabModeAsync, |
| - xwindow_, // confine_to |
| - None, // cursor |
| - CurrentTime) == GrabSuccess; |
| +#if XFIXES_MAJOR >= 5 |
| + if (pointer_barriers_.get()) |
|
Daniel Erat
2012/03/23 16:49:16
DCHECK(!pointer_barriers_.get()) instead?
oshima
2012/03/23 18:25:09
I added it. I kept "if" because this isn't critica
|
| + return false; |
| + // Monitors are vertically laid out, so just create barriers at the top and |
| + // the bottom. |
|
Daniel Erat
2012/03/23 16:49:16
Can the monitors be different widths? If so, it s
oshima
2012/03/23 18:25:09
There are already barriers on sides.
|
| + pointer_barriers_.reset(new XID[2]); |
| + pointer_barriers_[0] = XFixesCreatePointerBarrier( |
| + xdisplay_, xwindow_, |
| + 0, 0, bounds_.width(), 0, // barrier line |
|
Daniel Erat
2012/03/23 16:49:16
Should you be using bounds_.x() and bounds_.y() he
oshima
2012/03/23 18:25:09
I'm creating barriers relative to xwindow_, so thi
|
| + BarrierPositiveY, |
| + 0, NULL); // default device |
| + pointer_barriers_[1] = XFixesCreatePointerBarrier( |
| + xdisplay_, xwindow_, |
| + 0, bounds_.height(), bounds_.width(), bounds_.height(), // barrier line |
| + BarrierNegativeY, |
| + 0, NULL); // default device |
| +#endif |
| + return true; |
| } |
| void RootWindowHostLinux::UnConfineCursor() { |
|
Daniel Erat
2012/03/23 16:49:16
Should probably call this from the d'tor too.
oshima
2012/03/23 18:25:09
Good point. Done.
|
| - XUngrabPointer(xdisplay_, CurrentTime); |
| +#if XFIXES_MAJOR >= 5 |
| + if (pointer_barriers_.get()) { |
| + XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[0]); |
| + XFixesDestroyPointerBarrier(xdisplay_, pointer_barriers_[1]); |
| + pointer_barriers_.reset(); |
| + } |
| +#endif |
| } |
| void RootWindowHostLinux::MoveCursorTo(const gfx::Point& location) { |