Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Unified Diff: ui/aura/root_window_host_linux.cc

Issue 10905163: aura-x11: Fix touch-calibration for multi-monitor setups. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/base/events/event.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 9b9885670ea1a68b31e51af9f6a09b6dd5306db3..a643c56b2fee672ea480664368c63ce48827fd8c 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -51,6 +51,14 @@ const int kForwardMouseButton = 9;
const int kAnimatedCursorFrameDelayMs = 25;
+// These are the same values that are used to calibrate touch events in
+// |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc).
+// TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605)
+const int kXRootWindowPaddingLeft = 40;
+const int kXRootWindowPaddingRight = 40;
+const int kXRootWindowPaddingBottom = 30;
+const int kXRootWindowPaddingTop = 0;
+
const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__";
const char* kAtomsToCache[] = {
@@ -268,6 +276,38 @@ int CoalescePendingMotionEvents(const XEvent* xev, XEvent* last_event) {
return num_coalesed;
}
+void SelectEventsForRootWindow() {
+ XIEventMask evmask;
+ unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {};
+ memset(mask, 0, sizeof(mask));
+
+ XISetMask(mask, XI_HierarchyChanged);
+
+ XISetMask(mask, XI_KeyPress);
+ XISetMask(mask, XI_KeyRelease);
+
+#if defined(USE_XI2_MT)
+ XISetMask(mask, XI_TouchBegin);
+ XISetMask(mask, XI_TouchUpdate);
+ XISetMask(mask, XI_TouchEnd);
+#endif
+ XISetMask(mask, XI_ButtonPress);
+ XISetMask(mask, XI_ButtonRelease);
+ XISetMask(mask, XI_Motion);
+
+ evmask.deviceid = XIAllDevices;
+ evmask.mask_len = sizeof(mask);
+ evmask.mask = mask;
+
+ Display* display = ui::GetXDisplay();
+ ::Window root_window = ui::GetX11RootWindow();
+ XISelectEvents(display, root_window, &evmask, 1);
+
+ // Receive resize events for the root-window so |x_root_bounds_| can be
+ // updated.
+ XSelectInput(display, root_window, StructureNotifyMask);
+}
+
// We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only
// generated for certain keys; see
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per
@@ -531,6 +571,7 @@ RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
CWBackPixmap,
&swa);
base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
+ base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this);
prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
@@ -546,6 +587,13 @@ RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
if (base::MessagePumpForUI::HasXInput2())
ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
+ SelectEventsForRootWindow();
+
+ // Get the initial size of the X root window.
+ XWindowAttributes attrs;
+ XGetWindowAttributes(xdisplay_, x_root_window_, &attrs);
+ x_root_bounds_.SetRect(attrs.x, attrs.y, attrs.width, attrs.height);
+
// Initialize invisible cursor.
char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
XColor black;
@@ -593,6 +641,7 @@ RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
}
RootWindowHostLinux::~RootWindowHostLinux() {
+ base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this);
base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
UnConfineCursor();
@@ -648,38 +697,44 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
delegate_->OnHostLostCapture();
break;
case ConfigureNotify: {
- DCHECK_EQ(xwindow_, xev->xconfigure.window);
- DCHECK_EQ(xwindow_, xev->xconfigure.event);
- // 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.
- gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
- xev->xconfigure.width, xev->xconfigure.height);
- bool size_changed = bounds_.size() != bounds.size();
- bool origin_changed = bounds_.origin() != bounds.origin();
- bounds_ = bounds;
- // Update barrier and mouse location when the root window has
- // moved/resized.
- if (pointer_barriers_.get() && (size_changed || origin_changed)) {
- UnConfineCursor();
- RootWindow* root = delegate_->AsRootWindow();
- client::ScreenPositionClient* client =
+ if (xev->xconfigure.window == xwindow_) {
+ DCHECK_EQ(xwindow_, xev->xconfigure.event);
+ // 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.
+ gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
+ xev->xconfigure.width, xev->xconfigure.height);
+ bool size_changed = bounds_.size() != bounds.size();
+ bool origin_changed = bounds_.origin() != bounds.origin();
+ bounds_ = bounds;
+ // Update barrier and mouse location when the root window has
+ // moved/resized.
+ if (pointer_barriers_.get() && (size_changed || origin_changed)) {
+ UnConfineCursor();
+ RootWindow* root = delegate_->AsRootWindow();
+ client::ScreenPositionClient* client =
client::GetScreenPositionClient(root);
- if (client) {
- gfx::Point p = gfx::Screen::GetCursorScreenPoint();
- client->ConvertPointFromScreen(root, &p);
- if (root->ContainsPoint(p)) {
- root->ConvertPointToNativeScreen(&p);
- XWarpPointer(
- xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y());
+ if (client) {
+ gfx::Point p = gfx::Screen::GetCursorScreenPoint();
+ client->ConvertPointFromScreen(root, &p);
+ if (root->ContainsPoint(p)) {
+ root->ConvertPointToNativeScreen(&p);
+ XWarpPointer(
+ xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y());
+ }
}
+ ConfineCursorToRootWindow();
}
- ConfineCursorToRootWindow();
+ if (size_changed)
+ delegate_->OnHostResized(bounds.size());
+ if (origin_changed)
+ delegate_->OnHostMoved(bounds_.origin());
+ } else {
+ DCHECK_EQ(x_root_window_, xev->xconfigure.event);
+ DCHECK_EQ(x_root_window_, xev->xconfigure.window);
+ x_root_bounds_.SetRect(xev->xconfigure.x, xev->xconfigure.y,
+ xev->xconfigure.width, xev->xconfigure.height);
}
- if (size_changed)
- delegate_->OnHostResized(bounds.size());
- if (origin_changed)
- delegate_->OnHostMoved(bounds_.origin());
break;
}
case GenericEvent: {
@@ -700,6 +755,22 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
case ui::ET_TOUCH_PRESSED:
case ui::ET_TOUCH_RELEASED: {
ui::TouchEvent touchev(xev);
+ // X maps the touch-surface to the size of the X root-window. In
+ // multi-monitor setup, the X root-window size is a combination of
+ // both the monitor sizes. So it is necessary to remap the location of
+ // the event from the X root-window to the X host-window for the aura
+ // root-window.
+ touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size());
+ if (!bounds_.Contains(touchev.location())) {
+ // This might still be in the bezel region.
+ gfx::Rect expanded(bounds_);
+ expanded.Inset(-kXRootWindowPaddingLeft,
+ -kXRootWindowPaddingTop,
+ -kXRootWindowPaddingRight,
+ -kXRootWindowPaddingBottom);
+ if (!expanded.Contains(touchev.location()))
+ break;
+ }
delegate_->OnHostTouchEvent(&touchev);
break;
}
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/base/events/event.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698