summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-17 18:54:13 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-17 18:54:13 +0000
commit807c442a00884b10b585e07143367a82e305b53d (patch)
treea83259a942eb13045488137e3690f83a480716cc
parent7254c42e801fe843722cfafb9c7b3a54ab13bd02 (diff)
downloadchromium_src-807c442a00884b10b585e07143367a82e305b53d.zip
chromium_src-807c442a00884b10b585e07143367a82e305b53d.tar.gz
chromium_src-807c442a00884b10b585e07143367a82e305b53d.tar.bz2
Merge 176231: x11: Add a hack to detect touch-cancel events from X11.
> > The touch-end event chrome receives from X does not contain enough > information to know whether the event came because the user lifted > the finger, or something else happened in the system that triggered > the event. So add some hack to figure out whether to generate a > touch-release event or a touch-cancel event from the X touch-end event. > > BUG=169177 > > Review URL: https://codereview.chromium.org/11819054 TBR=sadrul@chromium.org Review URL: https://codereview.chromium.org/11975054 git-svn-id: svn://svn.chromium.org/chrome/branches/1364/src@177445 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/aura/root_window.cc6
-rw-r--r--ui/aura/root_window_host_linux.cc1
-rw-r--r--ui/base/x/events_x.cc37
3 files changed, 41 insertions, 3 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index d79c6ec..2449873 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -803,7 +803,11 @@ bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) {
Env::GetInstance()->set_touch_down(touch_ids_down_ != 0);
break;
- // Don't handle ET_TOUCH_CANCELLED since we always get a ET_TOUCH_RELEASED.
+ // Handle ET_TOUCH_CANCELLED only if it has a native event.
+ case ui::ET_TOUCH_CANCELLED:
+ if (!event->HasNativeEvent())
+ break;
+ // fallthrough
case ui::ET_TOUCH_RELEASED:
touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^
(1 << event->touch_id());
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc
index c15fad9..e3ececa 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -868,6 +868,7 @@ void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) {
xev = &last_event;
// fallthrough
case ui::ET_TOUCH_PRESSED:
+ case ui::ET_TOUCH_CANCELLED:
case ui::ET_TOUCH_RELEASED: {
ui::TouchEvent touchev(xev);
#if defined(OS_CHROMEOS)
diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc
index 116b867..14b8da1 100644
--- a/ui/base/x/events_x.cc
+++ b/ui/base/x/events_x.cc
@@ -479,6 +479,37 @@ class XModifierStateWatcher{
DISALLOW_COPY_AND_ASSIGN(XModifierStateWatcher);
};
+#if defined(USE_XI2_MT)
+// Detects if a touch event is a driver-generated 'special event'.
+// A 'special event' is a touch release or move event with maximum radius and
+// pressure at location (0, 0).
+// This needs to be done in a cleaner way: http://crbug.com/169256
+bool TouchEventIsGeneratedHack(const base::NativeEvent& native_event) {
+ XIDeviceEvent* event =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ CHECK(event->evtype == XI_TouchUpdate ||
+ event->evtype == XI_TouchEnd);
+
+ // Force is normalized to [0, 1].
+ if (ui::GetTouchForce(native_event) < 1.0f)
+ return false;
+
+ if (ui::EventLocationFromNative(native_event) != gfx::Point())
+ return false;
+
+ // Radius is in pixels, and the valuator is the diameter in pixels.
+ float radius = ui::GetTouchRadiusX(native_event), min, max;
+ unsigned int deviceid =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data)->sourceid;
+ if (!ui::ValuatorTracker::GetInstance()->GetValuatorRange(
+ deviceid, ui::ValuatorTracker::VAL_TOUCH_MAJOR, &min, &max)) {
+ return false;
+ }
+
+ return radius * 2 == max;
+}
+#endif
+
int GetEventFlagsFromXState(unsigned int state) {
int flags = 0;
if (state & ControlMask)
@@ -539,9 +570,11 @@ ui::EventType GetTouchEventType(const base::NativeEvent& native_event) {
case XI_TouchBegin:
return ui::ET_TOUCH_PRESSED;
case XI_TouchUpdate:
- return ui::ET_TOUCH_MOVED;
+ return TouchEventIsGeneratedHack(native_event) ? ui::ET_UNKNOWN :
+ ui::ET_TOUCH_MOVED;
case XI_TouchEnd:
- return ui::ET_TOUCH_RELEASED;
+ return TouchEventIsGeneratedHack(native_event) ? ui::ET_TOUCH_CANCELLED :
+ ui::ET_TOUCH_RELEASED;
}
return ui::ET_UNKNOWN;