diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-17 18:54:13 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-17 18:54:13 +0000 |
commit | 807c442a00884b10b585e07143367a82e305b53d (patch) | |
tree | a83259a942eb13045488137e3690f83a480716cc | |
parent | 7254c42e801fe843722cfafb9c7b3a54ab13bd02 (diff) | |
download | chromium_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.cc | 6 | ||||
-rw-r--r-- | ui/aura/root_window_host_linux.cc | 1 | ||||
-rw-r--r-- | ui/base/x/events_x.cc | 37 |
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; |