Fix mouse velocity calculation

The mouse event that is sent to QPlatformCursor is in native pixels,
but the QSinglePointEvent constructor sets QEventPoint::globalLastPosition
every time, and velocity is calculated by delta from globalLastPosition
to globalPosition.  We plan to rely on this velocity being correct
in Qt Quick, in Flickable for example.  So globalLastPosition and
globalPosition need to be in the same coordinate system at the time
QPointerEvent::setTimestamp() is called.

Change-Id: I39f97a43f55f47a70cbd574861e920f3106e2125
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Shawn Rutledge 2020-11-06 11:24:49 +01:00
parent 832e44b232
commit 604adc01c0

View File

@ -2151,6 +2151,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
bool positionChanged = QGuiApplicationPrivate::lastCursorPosition != e->globalPos;
bool mouseMove = false;
bool mousePress = false;
const QPointF lastGlobalPosition = QGuiApplicationPrivate::lastCursorPosition;
QPointF globalPoint = e->globalPos;
if (qIsNaN(e->globalPos.x()) || qIsNaN(e->globalPos.y())) {
@ -2279,13 +2280,19 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
button, e->buttons, e->modifiers, e->source, device);
ev.setTimestamp(e->timestamp);
// avoid incorrect velocity calculation: ev is in the native coordinate system,
// but we need to consistently use the logical coordinate system for velocity
// whenever QEventPoint::setTimestamp() is called
ev.QInputEvent::setTimestamp(e->timestamp);
cursor->pointerEvent(ev);
}
}
#endif
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, e->buttons, e->modifiers, e->source, device);
// restore globalLastPosition to avoid invalidating the velocity calculations,
// because the QPlatformCursor mouse event above was in native coordinates
QMutableEventPoint::from(persistentEPD->eventPoint).setGlobalLastPosition(lastGlobalPosition);
// ev now contains a detached copy of the QEventPoint from QPointingDevicePrivate::activePoints
ev.setTimestamp(e->timestamp);
if (window->d_func()->blockedByModalWindow && !qApp->d_func()->popupActive()) {