| Index: ui/aura/desktop_host_linux.cc
|
| diff --git a/ui/aura/desktop_host_linux.cc b/ui/aura/desktop_host_linux.cc
|
| index 9934467fcbb2b8b49208f0a45a5fcdf60137d293..34d9eb47efa058f30a43df7d2c9d2af761b84d96 100644
|
| --- a/ui/aura/desktop_host_linux.cc
|
| +++ b/ui/aura/desktop_host_linux.cc
|
| @@ -33,6 +33,53 @@ namespace aura {
|
|
|
| namespace {
|
|
|
| +// The events reported for slave devices can have incorrect information for some
|
| +// fields. This utility function is used to check for such inconsistencies.
|
| +void CheckXEventForConsistency(XEvent* xevent) {
|
| + static bool expect_master_event = false;
|
| + static XIDeviceEvent slave_event;
|
| + static gfx::Point slave_location;
|
| +
|
| + // Note: If an event comes from a slave pointer device, then it will be
|
| + // followed by the same event, but reported from its master pointer device.
|
| + // However, if the event comes from a floating slave device (e.g. a
|
| + // touchscreen), then it will not be followed by a duplicate event, since the
|
| + // floating slave isn't attached to a master.
|
| +
|
| + bool was_expecting_master_event = expect_master_event;
|
| + expect_master_event = false;
|
| +
|
| + if (!xevent || xevent->type != GenericEvent)
|
| + return;
|
| +
|
| + XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
|
| + if (xievent->evtype != XI_Motion &&
|
| + xievent->evtype != XI_ButtonPress &&
|
| + xievent->evtype != XI_ButtonRelease) {
|
| + return;
|
| + }
|
| +
|
| + if (xievent->sourceid == xievent->deviceid) {
|
| + slave_event = *xievent;
|
| + slave_location = ui::EventLocationFromNative(xevent);
|
| + expect_master_event = true;
|
| + } else if (was_expecting_master_event) {
|
| + CHECK_EQ(slave_location.x(), ui::EventLocationFromNative(xevent).x());
|
| + CHECK_EQ(slave_location.y(), ui::EventLocationFromNative(xevent).y());
|
| +
|
| + CHECK_EQ(slave_event.type, xievent->type);
|
| + CHECK_EQ(slave_event.evtype, xievent->evtype);
|
| + CHECK_EQ(slave_event.detail, xievent->detail);
|
| + CHECK_EQ(slave_event.flags, xievent->flags);
|
| + CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len);
|
| + CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len);
|
| + CHECK_EQ(slave_event.mods.base, xievent->mods.base);
|
| + CHECK_EQ(slave_event.mods.latched, xievent->mods.latched);
|
| + CHECK_EQ(slave_event.mods.locked, xievent->mods.locked);
|
| + CHECK_EQ(slave_event.mods.effective, xievent->mods.effective);
|
| + }
|
| +}
|
| +
|
| // Returns X font cursor shape from an Aura cursor.
|
| int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
|
| switch (native_cursor) {
|
| @@ -141,6 +188,7 @@ int CoalescePendingXIMotionEvents(const XEvent* xev, XEvent* last_event) {
|
| // with one from the master and one from the slave so there will
|
| // always be at least one pending.
|
| if (!ui::TouchFactory::GetInstance()->ShouldProcessXI2Event(&next_event)) {
|
| + CheckXEventForConsistency(&next_event);
|
| XFreeEventData(display, &next_event.xcookie);
|
| XNextEvent(display, &next_event);
|
| continue;
|
| @@ -169,6 +217,7 @@ int CoalescePendingXIMotionEvents(const XEvent* xev, XEvent* last_event) {
|
| // Get the event and its cookie data.
|
| XNextEvent(display, last_event);
|
| XGetEventData(display, &last_event->xcookie);
|
| + CheckXEventForConsistency(last_event);
|
| ++num_coalesed;
|
| continue;
|
| } else {
|
| @@ -280,6 +329,7 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds)
|
|
|
| long event_mask = ButtonPressMask | ButtonReleaseMask |
|
| KeyPressMask | KeyReleaseMask |
|
| + EnterWindowMask | LeaveWindowMask |
|
| ExposureMask | VisibilityChangeMask |
|
| StructureNotifyMask | PropertyChangeMask |
|
| PointerMotionMask;
|
| @@ -287,11 +337,8 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds)
|
| XSelectInput(xdisplay_, root_window_, StructureNotifyMask);
|
| XFlush(xdisplay_);
|
|
|
| - // TODO(sadrul): reenable once 103981 is fixed.
|
| -#if defined(TOUCH_UI)
|
| if (base::MessagePumpForUI::HasXInput2())
|
| ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
|
| -#endif
|
| }
|
|
|
| DesktopHostLinux::~DesktopHostLinux() {
|
| @@ -306,6 +353,9 @@ base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch(
|
| DLOG(WARNING) << "DispatchEvent:" << xev->type;
|
|
|
| bool handled = false;
|
| +
|
| + CheckXEventForConsistency(xev);
|
| +
|
| switch (xev->type) {
|
| case Expose:
|
| desktop_->Draw();
|
|
|