diff options
author | Gatis Paeglis <gatis.paeglis@qt.io> | 2017-09-04 09:48:08 +0200 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@qt.io> | 2017-10-10 22:09:22 +0000 |
commit | 72dfe1deb32bc1efcb71ea61a4de6e76ad396ee7 (patch) | |
tree | 6e659140647d6791651e223882100c1652c623bf /src/gui | |
parent | a37785ec7638e7485112b87dd7e767881fecc114 (diff) |
touch: use enhanced mouse event when synthesizing mouse
The documentation for AA_SynthesizeMouseForUnhandledTouchEvents states:
"All touch events that are not accepted by the application will be
translated to left button mouse events instead."
This is exactly what this patch does. With the enhanced mouse event,
we can simply pass event details as necessary. This should not conflict
with the code doing its own mouse synthesis (as long as custom event
handler accepts QEvent::Touch{Begin,Update,End}).
What was wrong with the previous implementation:
It was sharing the same state variable (mouse_buttons) to deduce button
state/type on physical mouse and emulated mouse. This was wrong, you
can't track state of two input devices by sharing one variable. Moreover,
this variable is intended for tracking state of a hardware mouse only.
Button state on physical mouse (as a separate pointer device) is
irrelevant for touch input (which is another "pointer device"). The
current API does not support multiple pointer devices, thus button state
on one pointer device should not affect state on other pointer device.
Task-number: QTBUG-57465
Task-number: QTBUG-52102
Change-Id: Id45d815508918b4e52319baddb2c9564d52ad783
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 80a6a9c1e4..20fe738469 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2528,7 +2528,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To ++it; } for (QSet<QWindow *>::const_iterator winIt = windowsNeedingCancel.constBegin(), - winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) { + winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) { touchEvent.setWindow(*winIt); QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent); } @@ -2541,8 +2541,10 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To e->timestamp, synthIt->pos, synthIt->screenPos, - mouse_buttons & ~Qt::LeftButton, + Qt::NoButton, e->modifiers, + Qt::LeftButton, + QEvent::MouseButtonRelease, Qt::MouseEventSynthesizedByQt); fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; processMouseEvent(&fake); @@ -2739,25 +2741,41 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To if (!e->synthetic() && !touchEvent.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) { // exclude devices which generate their own mouse events if (!(touchEvent.device()->capabilities() & QTouchDevice::MouseEmulation)) { - Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton; - if (b == Qt::NoButton) + + if (eventType == QEvent::TouchEnd) self->synthesizedMousePoints.clear(); const QList<QTouchEvent::TouchPoint> &touchPoints = touchEvent.touchPoints(); if (eventType == QEvent::TouchBegin) m_fakeMouseSourcePointId = touchPoints.first().id(); + const QEvent::Type mouseType = [&]() { + switch (eventType) { + case QEvent::TouchBegin: return QEvent::MouseButtonPress; + case QEvent::TouchUpdate: return QEvent::MouseMove; + case QEvent::TouchEnd: return QEvent::MouseButtonRelease; + default: Q_UNREACHABLE(); + } + }(); + + Qt::MouseButton button = mouseType == QEvent::MouseMove ? Qt::NoButton : Qt::LeftButton; + Qt::MouseButtons buttons = mouseType == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton; + for (int i = 0; i < touchPoints.count(); ++i) { const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); if (touchPoint.id() == m_fakeMouseSourcePointId) { - if (b != Qt::NoButton) + if (eventType != QEvent::TouchEnd) self->synthesizedMousePoints.insert(w, SynthesizedMouseData( touchPoint.pos(), touchPoint.screenPos(), w)); + // All touch events that are not accepted by the application will be translated to + // left mouse button events instead (see AA_SynthesizeMouseForUnhandledTouchEvents docs). QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp, touchPoint.pos(), touchPoint.screenPos(), - b | (mouse_buttons & ~Qt::LeftButton), + buttons, e->modifiers, + button, + mouseType, Qt::MouseEventSynthesizedByQt); fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; processMouseEvent(&fake); |