summaryrefslogtreecommitdiffstats
path: root/src/core/render_widget_host_view_qt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/render_widget_host_view_qt.cpp')
-rw-r--r--src/core/render_widget_host_view_qt.cpp53
1 files changed, 45 insertions, 8 deletions
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index eaf8485d3..27eda06a6 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -229,6 +229,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
: m_host(content::RenderWidgetHostImpl::From(widget))
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
+ , m_touchMotionStarted(false)
, m_chromiumCompositorData(new ChromiumCompositorData)
, m_needsDelegatedFrameAck(false)
, m_didFirstVisuallyNonEmptyLayout(false)
@@ -1005,6 +1006,12 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev)
m_host->ForwardWheelEvent(WebEventFactory::toWebWheelEvent(ev, dpiScale()));
}
+void RenderWidgetHostViewQt::clearPreviousTouchMotionState()
+{
+ m_previousTouchPoints.clear();
+ m_touchMotionStarted = false;
+}
+
void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
{
// Chromium expects the touch event timestamps to be comparable to base::TimeTicks::Now().
@@ -1019,19 +1026,46 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
QList<QTouchEvent::TouchPoint> touchPoints = mapTouchPointIds(ev->touchPoints());
- if (ev->type() == QEvent::TouchCancel) {
- MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::ACTION_CANCEL, ev->modifiers(), dpiScale());
+ switch (ev->type()) {
+ case QEvent::TouchBegin:
+ m_sendMotionActionDown = true;
+ m_touchMotionStarted = true;
+ break;
+ case QEvent::TouchUpdate:
+ m_touchMotionStarted = true;
+ break;
+ case QEvent::TouchCancel:
+ {
+ // Don't process a TouchCancel event if no motion was started beforehand, or if there are
+ // no touch points in the current event or in the previously processed event.
+ if (!m_touchMotionStarted || (touchPoints.isEmpty() && m_previousTouchPoints.isEmpty())) {
+ clearPreviousTouchMotionState();
+ return;
+ }
+
+ // Use last saved touch points for the cancel event, to get rid of a QList assert,
+ // because Chromium expects a MotionEvent::ACTION_CANCEL instance to contain at least
+ // one touch point, whereas a QTouchCancel may not contain any touch points at all.
+ if (touchPoints.isEmpty())
+ touchPoints = m_previousTouchPoints;
+ clearPreviousTouchMotionState();
+ MotionEventQt cancelEvent(touchPoints, eventTimestamp, ui::MotionEvent::ACTION_CANCEL,
+ ev->modifiers(), dpiScale());
processMotionEvent(cancelEvent);
return;
}
-
- if (ev->type() == QEvent::TouchBegin)
- m_sendMotionActionDown = true;
+ case QEvent::TouchEnd:
+ clearPreviousTouchMotionState();
+ break;
+ default:
+ break;
+ }
// Make sure that ACTION_POINTER_DOWN is delivered before ACTION_MOVE,
// and ACTION_MOVE before ACTION_POINTER_UP.
std::sort(touchPoints.begin(), touchPoints.end(), compareTouchPoints);
+ m_previousTouchPoints = touchPoints;
for (int i = 0; i < touchPoints.size(); ++i) {
ui::MotionEvent::Action action;
switch (touchPoints[i].state()) {
@@ -1039,21 +1073,24 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
if (m_sendMotionActionDown) {
action = ui::MotionEvent::ACTION_DOWN;
m_sendMotionActionDown = false;
- } else
+ } else {
action = ui::MotionEvent::ACTION_POINTER_DOWN;
+ }
break;
case Qt::TouchPointMoved:
action = ui::MotionEvent::ACTION_MOVE;
break;
case Qt::TouchPointReleased:
- action = touchPoints.size() > 1 ? ui::MotionEvent::ACTION_POINTER_UP : ui::MotionEvent::ACTION_UP;
+ action = touchPoints.size() > 1 ? ui::MotionEvent::ACTION_POINTER_UP :
+ ui::MotionEvent::ACTION_UP;
break;
default:
// Ignore Qt::TouchPointStationary
continue;
}
- MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), dpiScale(), i);
+ MotionEventQt motionEvent(touchPoints, eventTimestamp, action, ev->modifiers(), dpiScale(),
+ i);
processMotionEvent(motionEvent);
}
}