Skip to content

Commit 469db7f

Browse files
a-ilinjsfdez
authored andcommitted
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 <[email protected]>
1 parent 97275fc commit 469db7f

File tree

2 files changed

+73
-42
lines changed

2 files changed

+73
-42
lines changed

src/plugins/platforms/webgl/qwebglintegration.cpp

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -519,47 +519,59 @@ void QWebGLIntegrationPrivate::handleTouch(const ClientData &clientData, const Q
519519
auto window = findWindow(clientData, winId)->window();
520520
const auto time = object.value("time").toDouble();
521521
const auto eventType = object.value("event").toString();
522-
const auto changedTouch = object.value("changedTouches").toArray().first().toObject();
523-
const auto clientX = changedTouch.value("clientX").toDouble();
524-
const auto clientY = changedTouch.value("clientY").toDouble();
525-
QList<QWindowSystemInterface::TouchPoint> points;
526-
for (auto changedTouch : object.value("changedTouches").toArray()) {
527-
QWindowSystemInterface::TouchPoint point; // support more than one
528-
const auto pageX = changedTouch.toObject().value("pageX").toDouble();
529-
const auto pageY = changedTouch.toObject().value("pageY").toDouble();
530-
const auto radiousX = changedTouch.toObject().value("radiousX").toDouble();
531-
const auto radiousY = changedTouch.toObject().value("radiousY").toDouble();
532-
point.id = changedTouch.toObject().value("identifier").toInt(0);
533-
point.pressure = changedTouch.toObject().value("force").toDouble(1.);
534-
point.area.setX(pageX - radiousX);
535-
point.area.setY(pageY - radiousY);
536-
point.area.setWidth(radiousX * 2);
537-
point.area.setHeight(radiousY * 2);
538-
point.normalPosition.setX(changedTouch.toObject().value("normalPositionX").toDouble());
539-
point.normalPosition.setY(changedTouch.toObject().value("normalPositionY").toDouble());
540-
if (eventType == QStringLiteral("touchstart")) {
541-
point.state = Qt::TouchPointPressed;
542-
} else if (eventType == QStringLiteral("touchend")) {
543-
qCDebug(lcWebGL, ) << "end" << object;
544-
point.state = Qt::TouchPointReleased;
545-
} else if (eventType == QStringLiteral("touchcancel")) {
546-
QWindowSystemInterface::handleTouchCancelEvent(window,
547-
time,
548-
touchDevice,
549-
Qt::NoModifier);
550-
return;
551-
} else {
552-
point.state = Qt::TouchPointMoved;
522+
if (eventType == QStringLiteral("touchcancel")) {
523+
QWindowSystemInterface::handleTouchCancelEvent(window,
524+
time,
525+
touchDevice,
526+
Qt::NoModifier);
527+
} else {
528+
QList<QWindowSystemInterface::TouchPoint> points;
529+
auto touchToPoint = [](const QJsonValue &touch) -> QWindowSystemInterface::TouchPoint {
530+
QWindowSystemInterface::TouchPoint point; // support more than one
531+
const auto pageX = touch.toObject().value("pageX").toDouble();
532+
const auto pageY = touch.toObject().value("pageY").toDouble();
533+
const auto radiousX = touch.toObject().value("radiousX").toDouble();
534+
const auto radiousY = touch.toObject().value("radiousY").toDouble();
535+
const auto clientX = touch.toObject().value("clientX").toDouble();
536+
const auto clientY = touch.toObject().value("clientY").toDouble();
537+
point.id = touch.toObject().value("identifier").toInt(0);
538+
point.pressure = touch.toObject().value("force").toDouble(1.);
539+
point.area.setX(pageX - radiousX);
540+
point.area.setY(pageY - radiousY);
541+
point.area.setWidth(radiousX * 2);
542+
point.area.setHeight(radiousY * 2);
543+
point.normalPosition.setX(touch.toObject().value("normalPositionX").toDouble());
544+
point.normalPosition.setY(touch.toObject().value("normalPositionY").toDouble());
545+
point.rawPositions = {{ clientX, clientY }};
546+
return point;
547+
};
548+
549+
for (const auto &touch : object.value("changedTouches").toArray()) {
550+
auto point = touchToPoint(touch);
551+
if (eventType == QStringLiteral("touchstart")) {
552+
point.state = Qt::TouchPointPressed;
553+
} else if (eventType == QStringLiteral("touchend")) {
554+
qCDebug(lcWebGL, ) << "end" << object;
555+
point.state = Qt::TouchPointReleased;
556+
} else {
557+
Q_ASSERT(eventType == QStringLiteral("touchmove"));
558+
point.state = Qt::TouchPointMoved;
559+
}
560+
points.append(point);
553561
}
554-
point.rawPositions = {{ clientX, clientY }};
555-
points.append(point);
556-
}
557562

558-
QWindowSystemInterface::handleTouchEvent(window,
559-
time,
560-
touchDevice,
561-
points,
562-
Qt::NoModifier);
563+
for (const auto &touch : object.value("stationaryTouches").toArray()) {
564+
auto point = touchToPoint(touch);
565+
point.state = Qt::TouchPointStationary;
566+
points.append(point);
567+
}
568+
569+
QWindowSystemInterface::handleTouchEvent(window,
570+
time,
571+
touchDevice,
572+
points,
573+
Qt::NoModifier);
574+
}
563575
}
564576

565577
void QWebGLIntegrationPrivate::handleKeyboard(const ClientData &clientData,

src/plugins/platforms/webgl/webqt.jsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,9 @@ window.onload = function () {
289289
object["time"] = new Date().getTime();
290290
object["event"] = event.type;
291291
object["changedTouches"] = [];
292-
for (var i = 0; i < event.targetTouches.length; ++i) {
293-
var changedTouch = event.targetTouches[i];
292+
object["stationaryTouches"] = [];
293+
294+
var addTouch = function(changedTouch, isChanged) {
294295
var touch = {};
295296
touch["clientX"] = changedTouch.clientX;
296297
touch["clientY"] = changedTouch.clientY;
@@ -305,8 +306,26 @@ window.onload = function () {
305306
touch["screenY"] = changedTouch.screenY;
306307
touch["normalPositionX"] = changedTouch.screenX / screen.width;
307308
touch["normalPositionY"] = changedTouch.screenY / screen.height;
308-
object.changedTouches.push(touch);
309+
if (isChanged)
310+
object.changedTouches.push(touch);
311+
else
312+
object.stationaryTouches.push(touch);
313+
};
314+
315+
for (var i = 0; i < event.changedTouches.length; ++i) {
316+
var changedTouch = event.changedTouches[i];
317+
addTouch(changedTouch, true);
309318
}
319+
320+
for (var i = 0; i < event.targetTouches.length; ++i) {
321+
var targetTouch = event.targetTouches[i];
322+
if (object.changedTouches.findIndex(function(touch){
323+
return touch.identifier === targetTouch.identifier;
324+
}) === -1) {
325+
addTouch(targetTouch, false);
326+
}
327+
}
328+
310329
sendObject(object);
311330

312331
if (event.preventDefault && event.cancelable)

0 commit comments

Comments
 (0)