wasm: fix touchpoint handling

emscripten sends a touchstart event for every touch point when a new
touch point happens, so this makes them moved or stationary if already
known.

This allows QtQuick PinchArea to work.

Task-number: QTBUG-72214
Change-Id: I8e7c0cd2d78b07cfeae21491846cc31092359050
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Lorn Potter 2018-12-07 14:11:57 +10:00
parent e608b5d555
commit 11228e54b6
2 changed files with 49 additions and 23 deletions

View File

@ -695,7 +695,12 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
{ {
QWasmEventTranslator *eventTranslator = static_cast<QWasmEventTranslator *>(userData); auto translator = reinterpret_cast<QWasmEventTranslator*>(userData);
return translator->handleTouch(eventType, touchEvent);
}
int QWasmEventTranslator::handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent)
{
QList<QWindowSystemInterface::TouchPoint> touchPointList; QList<QWindowSystemInterface::TouchPoint> touchPointList;
touchPointList.reserve(touchEvent->numTouches); touchPointList.reserve(touchEvent->numTouches);
QWindow *window2; QWindow *window2;
@ -704,50 +709,68 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven
const EmscriptenTouchPoint *touches = &touchEvent->touches[i]; const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
QPoint point(touches->canvasX, touches->canvasY); QPoint point(touches->targetX, touches->targetY);
window2 = eventTranslator->screen()->compositor()->windowAt(point, 5); window2 = this->screen()->compositor()->windowAt(point, 5);
QWindowSystemInterface::TouchPoint touchPoint; QWindowSystemInterface::TouchPoint touchPoint;
auto cX = point.x();
auto cY = point.y();
touchPoint.area = QRect(0, 0, 8, 8); touchPoint.area = QRect(0, 0, 8, 8);
touchPoint.area.moveCenter(QPointF(cX,cY)); // simulate area
touchPoint.id = touches->identifier; touchPoint.id = touches->identifier;
touchPoint.normalPosition = QPointF(cX / window2->width(), cY / window2->height()); touchPoint.pressure = 1.0;
const QPointF screenPos(point);
touchPoint.area.moveCenter(screenPos);
const auto tp = pressedTouchIds.constFind(touchPoint.id);
if (tp != pressedTouchIds.constEnd())
touchPoint.normalPosition = tp.value();
QPointF normalPosition(screenPos.x() / window2->width(),
screenPos.y() / window2->height());
const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition);
touchPoint.normalPosition = normalPosition;
switch (eventType) { switch (eventType) {
case EMSCRIPTEN_EVENT_TOUCHSTART: case EMSCRIPTEN_EVENT_TOUCHSTART:
touchPoint.state = Qt::TouchPointPressed; if (tp != pressedTouchIds.constEnd()) {
touchPoint.state = (stationaryTouchPoint
? Qt::TouchPointStationary
: Qt::TouchPointMoved);
} else {
touchPoint.state = Qt::TouchPointPressed;
}
pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition);
break; break;
case EMSCRIPTEN_EVENT_TOUCHEND: case EMSCRIPTEN_EVENT_TOUCHEND:
touchPoint.state = Qt::TouchPointReleased; touchPoint.state = Qt::TouchPointReleased;
pressedTouchIds.remove(touchPoint.id);
break; break;
case EMSCRIPTEN_EVENT_TOUCHMOVE: case EMSCRIPTEN_EVENT_TOUCHMOVE:
touchPoint.state = Qt::TouchPointMoved; touchPoint.state = (stationaryTouchPoint
? Qt::TouchPointStationary
: Qt::TouchPointMoved);
pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition);
break; break;
default: default:
Q_UNREACHABLE(); break;
} }
touchPointList.append(touchPoint); touchPointList.append(touchPoint);
} }
QWasmEventTranslator *wasmEventTranslator = (QWasmEventTranslator*)userData; QFlags<Qt::KeyboardModifier> keyModifier = translatKeyModifier(touchEvent);
QFlags<Qt::KeyboardModifier> keyModifier = wasmEventTranslator->translatKeyModifier(touchEvent);
if (eventType != EMSCRIPTEN_EVENT_TOUCHCANCEL) QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(
QWindowSystemInterface::handleTouchEvent window2, getTimestamp(), touchDevice, touchPointList, keyModifier);
<QWindowSystemInterface::SynchronousDelivery>(window2, wasmEventTranslator->getTimestamp(),
wasmEventTranslator->touchDevice, if (eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL)
touchPointList, keyModifier); QWindowSystemInterface::handleTouchCancelEvent(window2, getTimestamp(), touchDevice, keyModifier);
else
QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(),
wasmEventTranslator->touchDevice, keyModifier);
QWasmEventDispatcher::maintainTimers(); QWasmEventDispatcher::maintainTimers();
return 1; return 0;
} }
quint64 QWasmEventTranslator::getTimestamp() quint64 QWasmEventTranslator::getTimestamp()

View File

@ -61,6 +61,7 @@ public:
void processEvents(); void processEvents();
void initEventHandlers(); void initEventHandlers();
int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent);
Q_SIGNALS: Q_SIGNALS:
void getWindowAt(const QPoint &point, QWindow **window); void getWindowAt(const QPoint &point, QWindow **window);
@ -114,6 +115,8 @@ private:
{ Qt::Key_U, Qt::Key_Ucircumflex} { Qt::Key_U, Qt::Key_Ucircumflex}
}; };
QMap <int, QPointF> pressedTouchIds;
private: private:
QWindow *draggedWindow; QWindow *draggedWindow;
QWindow *pressedWindow; QWindow *pressedWindow;