diff options
author | Aleksei Ilin <a.ilin@outlook.com> | 2017-10-02 22:46:17 +0200 |
---|---|---|
committer | Jesus Fernandez <Jesus.Fernandez@qt.io> | 2017-10-04 06:22:35 +0000 |
commit | 469db7f3839a0125f04874ebab1a1009d266621a (patch) | |
tree | 8e90e50ca13cbabe89aab5dfef9b67e011555006 | |
parent | 97275fc54abd103ae8f603027ce829ce3429c896 (diff) |
Fix multitouch support for mobile browsers
To work properly on each touch change all touch points
have to be provided, not only the changed ones.
The not changed touch points should have state
Qt::TouchPointStationary.
Change-Id: I13ea0336de489e02a00a6ff642bf6e1d8261bc21
Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io>
-rw-r--r-- | src/plugins/platforms/webgl/qwebglintegration.cpp | 90 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/webqt.jsx | 25 |
2 files changed, 73 insertions, 42 deletions
diff --git a/src/plugins/platforms/webgl/qwebglintegration.cpp b/src/plugins/platforms/webgl/qwebglintegration.cpp index 0d9902d..d86db07 100644 --- a/src/plugins/platforms/webgl/qwebglintegration.cpp +++ b/src/plugins/platforms/webgl/qwebglintegration.cpp @@ -519,47 +519,59 @@ void QWebGLIntegrationPrivate::handleTouch(const ClientData &clientData, const Q auto window = findWindow(clientData, winId)->window(); const auto time = object.value("time").toDouble(); const auto eventType = object.value("event").toString(); - const auto changedTouch = object.value("changedTouches").toArray().first().toObject(); - const auto clientX = changedTouch.value("clientX").toDouble(); - const auto clientY = changedTouch.value("clientY").toDouble(); - QList<QWindowSystemInterface::TouchPoint> points; - for (auto changedTouch : object.value("changedTouches").toArray()) { - QWindowSystemInterface::TouchPoint point; // support more than one - const auto pageX = changedTouch.toObject().value("pageX").toDouble(); - const auto pageY = changedTouch.toObject().value("pageY").toDouble(); - const auto radiousX = changedTouch.toObject().value("radiousX").toDouble(); - const auto radiousY = changedTouch.toObject().value("radiousY").toDouble(); - point.id = changedTouch.toObject().value("identifier").toInt(0); - point.pressure = changedTouch.toObject().value("force").toDouble(1.); - point.area.setX(pageX - radiousX); - point.area.setY(pageY - radiousY); - point.area.setWidth(radiousX * 2); - point.area.setHeight(radiousY * 2); - point.normalPosition.setX(changedTouch.toObject().value("normalPositionX").toDouble()); - point.normalPosition.setY(changedTouch.toObject().value("normalPositionY").toDouble()); - if (eventType == QStringLiteral("touchstart")) { - point.state = Qt::TouchPointPressed; - } else if (eventType == QStringLiteral("touchend")) { - qCDebug(lcWebGL, ) << "end" << object; - point.state = Qt::TouchPointReleased; - } else if (eventType == QStringLiteral("touchcancel")) { - QWindowSystemInterface::handleTouchCancelEvent(window, - time, - touchDevice, - Qt::NoModifier); - return; - } else { - point.state = Qt::TouchPointMoved; + if (eventType == QStringLiteral("touchcancel")) { + QWindowSystemInterface::handleTouchCancelEvent(window, + time, + touchDevice, + Qt::NoModifier); + } else { + QList<QWindowSystemInterface::TouchPoint> points; + auto touchToPoint = [](const QJsonValue &touch) -> QWindowSystemInterface::TouchPoint { + QWindowSystemInterface::TouchPoint point; // support more than one + const auto pageX = touch.toObject().value("pageX").toDouble(); + const auto pageY = touch.toObject().value("pageY").toDouble(); + const auto radiousX = touch.toObject().value("radiousX").toDouble(); + const auto radiousY = touch.toObject().value("radiousY").toDouble(); + const auto clientX = touch.toObject().value("clientX").toDouble(); + const auto clientY = touch.toObject().value("clientY").toDouble(); + point.id = touch.toObject().value("identifier").toInt(0); + point.pressure = touch.toObject().value("force").toDouble(1.); + point.area.setX(pageX - radiousX); + point.area.setY(pageY - radiousY); + point.area.setWidth(radiousX * 2); + point.area.setHeight(radiousY * 2); + point.normalPosition.setX(touch.toObject().value("normalPositionX").toDouble()); + point.normalPosition.setY(touch.toObject().value("normalPositionY").toDouble()); + point.rawPositions = {{ clientX, clientY }}; + return point; + }; + + for (const auto &touch : object.value("changedTouches").toArray()) { + auto point = touchToPoint(touch); + if (eventType == QStringLiteral("touchstart")) { + point.state = Qt::TouchPointPressed; + } else if (eventType == QStringLiteral("touchend")) { + qCDebug(lcWebGL, ) << "end" << object; + point.state = Qt::TouchPointReleased; + } else { + Q_ASSERT(eventType == QStringLiteral("touchmove")); + point.state = Qt::TouchPointMoved; + } + points.append(point); } - point.rawPositions = {{ clientX, clientY }}; - points.append(point); - } - QWindowSystemInterface::handleTouchEvent(window, - time, - touchDevice, - points, - Qt::NoModifier); + for (const auto &touch : object.value("stationaryTouches").toArray()) { + auto point = touchToPoint(touch); + point.state = Qt::TouchPointStationary; + points.append(point); + } + + QWindowSystemInterface::handleTouchEvent(window, + time, + touchDevice, + points, + Qt::NoModifier); + } } void QWebGLIntegrationPrivate::handleKeyboard(const ClientData &clientData, diff --git a/src/plugins/platforms/webgl/webqt.jsx b/src/plugins/platforms/webgl/webqt.jsx index 02a05df..05d3425 100644 --- a/src/plugins/platforms/webgl/webqt.jsx +++ b/src/plugins/platforms/webgl/webqt.jsx @@ -289,8 +289,9 @@ window.onload = function () { object["time"] = new Date().getTime(); object["event"] = event.type; object["changedTouches"] = []; - for (var i = 0; i < event.targetTouches.length; ++i) { - var changedTouch = event.targetTouches[i]; + object["stationaryTouches"] = []; + + var addTouch = function(changedTouch, isChanged) { var touch = {}; touch["clientX"] = changedTouch.clientX; touch["clientY"] = changedTouch.clientY; @@ -305,8 +306,26 @@ window.onload = function () { touch["screenY"] = changedTouch.screenY; touch["normalPositionX"] = changedTouch.screenX / screen.width; touch["normalPositionY"] = changedTouch.screenY / screen.height; - object.changedTouches.push(touch); + if (isChanged) + object.changedTouches.push(touch); + else + object.stationaryTouches.push(touch); + }; + + for (var i = 0; i < event.changedTouches.length; ++i) { + var changedTouch = event.changedTouches[i]; + addTouch(changedTouch, true); } + + for (var i = 0; i < event.targetTouches.length; ++i) { + var targetTouch = event.targetTouches[i]; + if (object.changedTouches.findIndex(function(touch){ + return touch.identifier === targetTouch.identifier; + }) === -1) { + addTouch(targetTouch, false); + } + } + sendObject(object); if (event.preventDefault && event.cancelable) |