Decide whether to synthesize mouse events on a per device basis

Currently Qt uses the QPlatformIntegration::StyleHint
SynthesizeMouseFromTouchEvents to check whether to synthesize mouse
events from touch events. But not only platform plugins can produce
touch events, they can be created by e.g. QTest::touchEvent() and in
this case we almost definitely need synthesizing regardless of the
platform.

This commit introduces a QTouchDevice::MouseEmulation capability which
replaces use of the QPlatformIntegration::SynthesizeMouseFromTouchEvents.
So it's possible to pass QTouchDevice without this capability to
QTest::touchEvent() and be sure that mouse events will be synthesized.
Notice that touch pads always emulate mouse events.
As a result we can activate some tests which were disabled for specific
platform configurations by commits 6c1670d8c2
and e9760f1559.

Change-Id: Idc82fa4007a095fc1cb5934979361b0023d2b793
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
This commit is contained in:
Alexander Volkov 2014-12-09 18:52:24 +03:00
parent ef22739f47
commit 76922a706f
20 changed files with 85 additions and 66 deletions

View File

@ -788,12 +788,6 @@ bool QGuiApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blocking
return false; return false;
} }
bool QGuiApplicationPrivate::synthesizeMouseFromTouchEventsEnabled()
{
return QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)
&& QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::SynthesizeMouseFromTouchEvents).toBool();
}
/*! /*!
Returns the QWindow that receives events tied to focus, Returns the QWindow that receives events tied to focus,
such as key events. such as key events.
@ -2423,9 +2417,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
} }
QGuiApplication::sendSpontaneousEvent(w, &touchEvent); QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
if (!e->synthetic() && !touchEvent.isAccepted() && synthesizeMouseFromTouchEventsEnabled()) { if (!e->synthetic() && !touchEvent.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) {
// exclude touchpads as those generate their own mouse events // exclude devices which generate their own mouse events
if (touchEvent.device()->type() != QTouchDevice::TouchPad) { if (!(touchEvent.device()->capabilities() & QTouchDevice::MouseEmulation)) {
Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton; Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton;
if (b == Qt::NoButton) if (b == Qt::NoButton)
self->synthesizedMousePoints.clear(); self->synthesizedMousePoints.clear();

View File

@ -190,8 +190,6 @@ public:
static void updateBlockedStatus(QWindow *window); static void updateBlockedStatus(QWindow *window);
virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const; virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const;
static bool synthesizeMouseFromTouchEventsEnabled();
static Qt::MouseButtons buttons; static Qt::MouseButtons buttons;
static ulong mousePressTime; static ulong mousePressTime;
static Qt::MouseButton mousePressButton; static Qt::MouseButton mousePressButton;

View File

@ -386,8 +386,6 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return QPlatformTheme::defaultThemeHint(QPlatformTheme::StartDragVelocity); return QPlatformTheme::defaultThemeHint(QPlatformTheme::StartDragVelocity);
case UseRtlExtensions: case UseRtlExtensions:
return QVariant(false); return QVariant(false);
case SynthesizeMouseFromTouchEvents:
return true;
case SetFocusOnTouchRelease: case SetFocusOnTouchRelease:
return QVariant(false); return QVariant(false);
case MousePressAndHoldInterval: case MousePressAndHoldInterval:

View File

@ -141,7 +141,6 @@ public:
FontSmoothingGamma, FontSmoothingGamma,
StartDragVelocity, StartDragVelocity,
UseRtlExtensions, UseRtlExtensions,
SynthesizeMouseFromTouchEvents,
PasswordMaskCharacter, PasswordMaskCharacter,
SetFocusOnTouchRelease, SetFocusOnTouchRelease,
ShowIsMaximized, ShowIsMaximized,

View File

@ -96,6 +96,9 @@ QT_BEGIN_NAMESPACE
\value NormalizedPosition Indicates that the normalized position is available, meaning that normalizedPos() \value NormalizedPosition Indicates that the normalized position is available, meaning that normalizedPos()
returns a valid value. returns a valid value.
\value MouseEmulation Indicates that the device synthesizes mouse events.
This enum value has been introduced in Qt 5.5.
*/ */
/*! /*!

View File

@ -55,7 +55,8 @@ public:
Pressure = 0x0004, Pressure = 0x0004,
Velocity = 0x0008, Velocity = 0x0008,
RawPositions = 0x0010, RawPositions = 0x0010,
NormalizedPosition = 0x0020 NormalizedPosition = 0x0020,
MouseEmulation = 0x0040
}; };
Q_DECLARE_FLAGS(Capabilities, CapabilityFlag) Q_DECLARE_FLAGS(Capabilities, CapabilityFlag)

View File

@ -505,8 +505,6 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const
{ {
if (hint == QPlatformIntegration::FontSmoothingGamma) if (hint == QPlatformIntegration::FontSmoothingGamma)
return 2.0; return 2.0;
if (hint == QPlatformIntegration::SynthesizeMouseFromTouchEvents)
return false;
return QPlatformIntegration::styleHint(hint); return QPlatformIntegration::styleHint(hint);
} }

View File

@ -157,7 +157,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (!touchDevice) { if (!touchDevice) {
touchDevice = new QTouchDevice; touchDevice = new QTouchDevice;
touchDevice->setType(QTouchDevice::TouchPad); touchDevice->setType(QTouchDevice::TouchPad);
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice); QWindowSystemInterface::registerTouchDevice(touchDevice);
} }
} }

View File

@ -1235,6 +1235,11 @@ void QWindowsContext::setAsyncExpose(bool value)
d->m_asyncExpose = value; d->m_asyncExpose = value;
} }
QTouchDevice *QWindowsContext::touchDevice() const
{
return d->m_mouseHandler.touchDevice();
}
/*! /*!
\brief Windows functions for actual windows. \brief Windows functions for actual windows.

View File

@ -67,6 +67,7 @@ struct QWindowCreationContext;
struct QWindowsContextPrivate; struct QWindowsContextPrivate;
class QPoint; class QPoint;
class QKeyEvent; class QKeyEvent;
class QTouchDevice;
#ifndef Q_OS_WINCE #ifndef Q_OS_WINCE
struct QWindowsUser32DLL struct QWindowsUser32DLL
@ -219,6 +220,8 @@ public:
bool asyncExpose() const; bool asyncExpose() const;
void setAsyncExpose(bool value); void setAsyncExpose(bool value);
QTouchDevice *touchDevice() const;
private: private:
void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w); void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w);
#ifndef QT_NO_CONTEXTMENU #ifndef QT_NO_CONTEXTMENU

View File

@ -227,6 +227,18 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
qCDebug(lcQpaWindows) qCDebug(lcQpaWindows)
<< __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling=" << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling="
<< QWindowsScaling::factor(); << QWindowsScaling::factor();
QTouchDevice *touchDevice = m_context.touchDevice();
if (touchDevice) {
#ifdef Q_OS_WINCE
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
#else
if (!(m_options & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) {
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
}
#endif
QWindowSystemInterface::registerTouchDevice(touchDevice);
}
} }
QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()
@ -496,13 +508,6 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co
break; break;
case QPlatformIntegration::UseRtlExtensions: case QPlatformIntegration::UseRtlExtensions:
return QVariant(d->m_context.useRTLExtensions()); return QVariant(d->m_context.useRTLExtensions());
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
#ifdef Q_OS_WINCE
// We do not want Qt to synthesize mouse events as Windows also does that.
return false;
#else // Q_OS_WINCE
return QVariant(bool(d->m_options & DontPassOsMouseEventsSynthesizedFromTouch));
#endif // !Q_OS_WINCE
default: default:
break; break;
} }

View File

@ -128,7 +128,10 @@ static inline QTouchDevice *createTouchDevice()
QTouchDevice *result = new QTouchDevice; QTouchDevice *result = new QTouchDevice;
result->setType(digitizers & QT_NID_INTEGRATED_TOUCH result->setType(digitizers & QT_NID_INTEGRATED_TOUCH
? QTouchDevice::TouchScreen : QTouchDevice::TouchPad); ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad);
result->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition); QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition;
if (result->type() == QTouchDevice::TouchPad)
capabilities |= QTouchDevice::MouseEmulation;
result->setCapabilities(capabilities);
result->setMaximumTouchPoints(maxTouchPoints); result->setMaximumTouchPoints(maxTouchPoints);
return result; return result;
} }
@ -150,8 +153,6 @@ QWindowsMouseHandler::QWindowsMouseHandler() :
m_leftButtonDown(false), m_leftButtonDown(false),
m_previousCaptureWindow(0) m_previousCaptureWindow(0)
{ {
if (m_touchDevice)
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
} }
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()

View File

@ -224,8 +224,6 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint)
return defaultThemeHint(StartDragVelocity); return defaultThemeHint(StartDragVelocity);
case QPlatformIntegration::UseRtlExtensions: case QPlatformIntegration::UseRtlExtensions:
return false; return false;
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
return true;
case QPlatformIntegration::PasswordMaskCharacter: case QPlatformIntegration::PasswordMaskCharacter:
return defaultThemeHint(PasswordMaskCharacter); return defaultThemeHint(PasswordMaskCharacter);
case QPlatformIntegration::SetFocusOnTouchRelease: case QPlatformIntegration::SetFocusOnTouchRelease:

View File

@ -299,7 +299,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
, has_shape_extension(false) , has_shape_extension(false)
, has_randr_extension(false) , has_randr_extension(false)
, has_input_shape(false) , has_input_shape(false)
, has_touch_without_mouse_emulation(false)
, has_xkb(false) , has_xkb(false)
, m_buttons(0) , m_buttons(0)
, m_focusWindow(0) , m_focusWindow(0)

View File

@ -442,7 +442,6 @@ public:
bool hasXShape() const { return has_shape_extension; } bool hasXShape() const { return has_shape_extension; }
bool hasXRandr() const { return has_randr_extension; } bool hasXRandr() const { return has_randr_extension; }
bool hasInputShape() const { return has_input_shape; } bool hasInputShape() const { return has_input_shape; }
bool hasTouchWithoutMouseEmulation() const { return has_touch_without_mouse_emulation; }
bool hasXKB() const { return has_xkb; } bool hasXKB() const { return has_xkb; }
bool supportsThreadedRendering() const { return m_reader->isRunning(); } bool supportsThreadedRendering() const { return m_reader->isRunning(); }
@ -609,7 +608,6 @@ private:
bool has_shape_extension; bool has_shape_extension;
bool has_randr_extension; bool has_randr_extension;
bool has_input_shape; bool has_input_shape;
bool has_touch_without_mouse_emulation;
bool has_xkb; bool has_xkb;
Qt::MouseButtons m_buttons; Qt::MouseButtons m_buttons;

View File

@ -282,14 +282,14 @@ void QXcbConnection::xi2Select(xcb_window_t window)
mask.mask_len = sizeof(bitMask); mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask; mask.mask = xiBitMask;
if (!m_touchDevices.isEmpty()) { if (!m_touchDevices.isEmpty()) {
mask.deviceid = XIAllMasterDevices;
Status result = XISelectEvents(xDisplay, window, &mask, 1);
// If we select for touch events on the master pointer, XInput2 // If we select for touch events on the master pointer, XInput2
// will not synthesize mouse events. This means Qt must do it, // will not synthesize mouse events. This means Qt must do it,
// which is also preferable, since Qt can control better when // which is also preferable, since Qt can control better when
// to do so. // to do so.
if (result == Success) mask.deviceid = XIAllMasterDevices;
has_touch_without_mouse_emulation = true; Status result = XISelectEvents(xDisplay, window, &mask, 1);
if (result != Success)
qCDebug(lcQpaXInput, "XInput 2.2: failed to select touch events, window %x, result %d", window, result);
} }
} }
#endif // XCB_USE_XINPUT22 #endif // XCB_USE_XINPUT22
@ -424,6 +424,9 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
dev->size.width() > 10000 || dev->size.height() > 10000) dev->size.width() > 10000 || dev->size.height() > 10000)
dev->size = QSizeF(130, 110); dev->size = QSizeF(130, 110);
} }
if (!isUsingXInput22() || type == QTouchDevice::TouchPad)
caps |= QTouchDevice::MouseEmulation;
if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) { if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) {
dev->qtTouchDevice = new QTouchDevice; dev->qtTouchDevice = new QTouchDevice;
dev->qtTouchDevice->setName(QString::fromUtf8(dev->xiDeviceInfo->name)); dev->qtTouchDevice->setName(QString::fromUtf8(dev->xiDeviceInfo->name));

View File

@ -374,9 +374,6 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
// X11 always has support for windows, but the // X11 always has support for windows, but the
// window manager could prevent it (e.g. matchbox) // window manager could prevent it (e.g. matchbox)
return false; return false;
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
// We do not want Qt to synthesize mouse events if X11 already does it.
return m_connections.at(0)->hasTouchWithoutMouseEmulation();
default: default:
break; break;
} }

View File

@ -68,6 +68,7 @@ private slots:
void isActive(); void isActive();
void testInputEvents(); void testInputEvents();
void touchToMouseTranslation(); void touchToMouseTranslation();
void touchToMouseTranslationForDevices();
void mouseToTouchTranslation(); void mouseToTouchTranslation();
void mouseToTouchLoop(); void mouseToTouchLoop();
void touchCancel(); void touchCancel();
@ -705,8 +706,6 @@ void tst_QWindow::testInputEvents()
void tst_QWindow::touchToMouseTranslation() void tst_QWindow::touchToMouseTranslation()
{ {
if (!QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::SynthesizeMouseFromTouchEvents).toBool())
QSKIP("Mouse events are synthesized by the system on this platform.");
InputTestWindow window; InputTestWindow window;
window.ignoreTouch = true; window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
@ -779,6 +778,35 @@ void tst_QWindow::touchToMouseTranslation()
QTRY_COMPARE(window.mouseReleaseButton, 0); QTRY_COMPARE(window.mouseReleaseButton, 0);
} }
void tst_QWindow::touchToMouseTranslationForDevices()
{
InputTestWindow window;
window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QPoint touchPoint(10, 10);
QTest::touchEvent(&window, touchDevice).press(0, touchPoint, &window);
QTest::touchEvent(&window, touchDevice).release(0, touchPoint, &window);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressedCount, 1);
QCOMPARE(window.mouseReleasedCount, 1);
window.resetCounters();
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
QTest::touchEvent(&window, touchDevice).press(0, touchPoint, &window);
QTest::touchEvent(&window, touchDevice).release(0, touchPoint, &window);
QCoreApplication::processEvents();
touchDevice->setCapabilities(touchDevice->capabilities() & ~QTouchDevice::MouseEmulation);
QCOMPARE(window.mousePressedCount, 0);
QCOMPARE(window.mouseReleasedCount, 0);
}
void tst_QWindow::mouseToTouchTranslation() void tst_QWindow::mouseToTouchTranslation()
{ {
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true); qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
@ -907,8 +935,6 @@ void tst_QWindow::touchCancel()
void tst_QWindow::touchCancelWithTouchToMouse() void tst_QWindow::touchCancelWithTouchToMouse()
{ {
if (!QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::SynthesizeMouseFromTouchEvents).toBool())
QSKIP("Mouse events are synthesized by the system on this platform.");
InputTestWindow window; InputTestWindow window;
window.ignoreTouch = true; window.ignoreTouch = true;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize)); window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));

View File

@ -2006,9 +2006,6 @@ void tst_QApplication::touchEventPropagation()
int argc = 1; int argc = 1;
QApplication app(argc, &argv0); QApplication app(argc, &argv0);
const bool mouseEventSynthesizing = QGuiApplicationPrivate::platformIntegration()
->styleHint(QPlatformIntegration::SynthesizeMouseFromTouchEvents).toBool();
QList<QTouchEvent::TouchPoint> pressedTouchPoints; QList<QTouchEvent::TouchPoint> pressedTouchPoints;
QTouchEvent::TouchPoint press(0); QTouchEvent::TouchPoint press(0);
press.setState(Qt::TouchPointPressed); press.setState(Qt::TouchPointPressed);
@ -2047,7 +2044,7 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenTouchEvent);
QCOMPARE(window.seenMouseEvent, mouseEventSynthesizing); // QApplication may transform ignored touch events in mouse events QVERIFY(window.seenMouseEvent); // QApplication may transform ignored touch events in mouse events
window.reset(); window.reset();
window.setAttribute(Qt::WA_AcceptTouchEvents); window.setAttribute(Qt::WA_AcceptTouchEvents);
@ -2061,7 +2058,7 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(window.seenTouchEvent); QVERIFY(window.seenTouchEvent);
QCOMPARE(window.seenMouseEvent, mouseEventSynthesizing); QVERIFY(window.seenMouseEvent);
window.reset(); window.reset();
window.acceptTouchEvent = true; window.acceptTouchEvent = true;
@ -2100,9 +2097,9 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenTouchEvent);
QCOMPARE(widget.seenMouseEvent, mouseEventSynthesizing); QVERIFY(widget.seenMouseEvent);
QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenTouchEvent);
QCOMPARE(window.seenMouseEvent, mouseEventSynthesizing); QVERIFY(window.seenMouseEvent);
window.reset(); window.reset();
widget.reset(); widget.reset();
@ -2117,9 +2114,9 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(widget.seenTouchEvent); QVERIFY(widget.seenTouchEvent);
QCOMPARE(widget.seenMouseEvent, mouseEventSynthesizing); QVERIFY(widget.seenMouseEvent);
QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenTouchEvent);
QCOMPARE(window.seenMouseEvent, mouseEventSynthesizing); QVERIFY(window.seenMouseEvent);
window.reset(); window.reset();
widget.reset(); widget.reset();
@ -2134,7 +2131,7 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(widget.seenTouchEvent); QVERIFY(widget.seenTouchEvent);
QCOMPARE(widget.seenMouseEvent, mouseEventSynthesizing); QVERIFY(widget.seenMouseEvent);
QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenTouchEvent);
QVERIFY(!window.seenMouseEvent); QVERIFY(!window.seenMouseEvent);
@ -2169,9 +2166,9 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenTouchEvent);
QCOMPARE(widget.seenMouseEvent, mouseEventSynthesizing); QVERIFY(widget.seenMouseEvent);
QVERIFY(window.seenTouchEvent); QVERIFY(window.seenTouchEvent);
QCOMPARE(window.seenMouseEvent, mouseEventSynthesizing); QVERIFY(window.seenMouseEvent);
window.reset(); window.reset();
widget.reset(); widget.reset();
@ -2186,13 +2183,13 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenTouchEvent);
QCOMPARE(widget.seenMouseEvent, mouseEventSynthesizing); QVERIFY(!widget.seenMouseEvent);
QVERIFY(window.seenTouchEvent); QVERIFY(window.seenTouchEvent);
QVERIFY(!window.seenMouseEvent); QVERIFY(!window.seenMouseEvent);
window.reset(); window.reset();
widget.reset(); widget.reset();
widget.acceptMouseEvent = true; // it matters, touch events are propagated in parallel to synthesized mouse events widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first
window.acceptTouchEvent = true; window.acceptTouchEvent = true;
QWindowSystemInterface::handleTouchEvent(window.windowHandle(), QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
0, 0,
@ -2204,8 +2201,8 @@ void tst_QApplication::touchEventPropagation()
touchPointList(releasedTouchPoints)); touchPointList(releasedTouchPoints));
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenTouchEvent);
QCOMPARE(widget.seenMouseEvent, mouseEventSynthesizing); QVERIFY(!widget.seenMouseEvent);
QCOMPARE(!window.seenTouchEvent, mouseEventSynthesizing); QVERIFY(window.seenTouchEvent);
QVERIFY(!window.seenMouseEvent); QVERIFY(!window.seenMouseEvent);
} }
} }

View File

@ -9824,9 +9824,6 @@ public:
void tst_QWidget::touchEventSynthesizedMouseEvent() void tst_QWidget::touchEventSynthesizedMouseEvent()
{ {
// Pass if the platform does not want mouse event synhesizing
if (!QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::SynthesizeMouseFromTouchEvents).toBool())
return;
if (m_platform == QStringLiteral("wayland")) if (m_platform == QStringLiteral("wayland"))
QSKIP("Wayland: This fails. Figure out why."); QSKIP("Wayland: This fails. Figure out why.");
@ -9852,7 +9849,7 @@ void tst_QWidget::touchEventSynthesizedMouseEvent()
QCOMPARE(widget.m_lastMouseEventPos, QPointF(15, 15)); QCOMPARE(widget.m_lastMouseEventPos, QPointF(15, 15));
QTest::touchEvent(&widget, device).release(0, QPoint(20, 20), &widget); QTest::touchEvent(&widget, device).release(0, QPoint(20, 20), &widget);
QCOMPARE(widget.m_touchEventCount, 0); QCOMPARE(widget.m_touchEventCount, 0);
QCOMPARE(widget.m_mouseEventCount, 3); QCOMPARE(widget.m_mouseEventCount, 4); // we receive extra mouse move event
QCOMPARE(widget.m_lastMouseEventPos, QPointF(20, 20)); QCOMPARE(widget.m_lastMouseEventPos, QPointF(20, 20));
} }
@ -9903,8 +9900,7 @@ void tst_QWidget::touchEventSynthesizedMouseEvent()
QCOMPARE(parent.m_touchEventCount, 1); QCOMPARE(parent.m_touchEventCount, 1);
QCOMPARE(parent.m_mouseEventCount, 0); QCOMPARE(parent.m_mouseEventCount, 0);
QCOMPARE(child.m_touchEventCount, 0); QCOMPARE(child.m_touchEventCount, 0);
QCOMPARE(child.m_mouseEventCount, 1); // Attempt at mouse event before propagation QCOMPARE(child.m_mouseEventCount, 0);
QCOMPARE(child.m_lastMouseEventPos, QPointF(10, 10));
} }
{ {