QGuiApplication: port the last user of QMutableEventPoint::from()

... to the new static setter API, preventing the undefined behavior
that from() depended on.

Remove from() and constFrom().

Task-number: QTBUG-99615
Pick-to: 6.3
Change-Id: I69c52aa286eaf51303734e42184af36815cf828a
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Marc Mutz 2022-01-07 12:26:21 +01:00 committed by Shawn Rutledge
parent 3215416e3c
commit 31669722d9
3 changed files with 40 additions and 44 deletions

View File

@ -524,8 +524,8 @@ void QMutableEventPoint::detach(QEventPoint &p)
}
/*! \internal
Update current state from the given \a other point, assuming that this
instance contains state from the previous event and \a other contains new
Update \a target state from the \a other point, assuming that \a target
contains state from the previous event and \a other contains new
values that came in from a device.
That is: global position and other valuators will be updated, but
@ -537,40 +537,40 @@ void QMutableEventPoint::detach(QEventPoint &p)
\li properties that should be persistent between events (such as grabbers)
\endlist
*/
void QMutableEventPoint::updateFrom(const QEventPoint &other)
void QMutableEventPoint::update(const QEventPoint &other, QEventPoint &target)
{
detach();
setPressure(other.pressure());
detach(target);
setPressure(target, other.pressure());
switch (other.state()) {
case QEventPoint::State::Pressed:
setGlobalPressPosition(other.globalPosition());
setGlobalLastPosition(other.globalPosition());
if (pressure() < 0)
setPressure(1);
setGlobalPressPosition(target, other.globalPosition());
setGlobalLastPosition(target, other.globalPosition());
if (target.pressure() < 0)
setPressure(target, 1);
break;
case QEventPoint::State::Released:
if (globalPosition() != other.globalPosition())
setGlobalLastPosition(globalPosition());
setPressure(0);
if (target.globalPosition() != other.globalPosition())
setGlobalLastPosition(target, target.globalPosition());
setPressure(target, 0);
break;
default: // update or stationary
if (globalPosition() != other.globalPosition())
setGlobalLastPosition(globalPosition());
if (pressure() < 0)
setPressure(1);
if (target.globalPosition() != other.globalPosition())
setGlobalLastPosition(target, target.globalPosition());
if (target.pressure() < 0)
setPressure(target, 1);
break;
}
setState(other.state());
setPosition(other.position());
setScenePosition(other.scenePosition());
setGlobalPosition(other.globalPosition());
setEllipseDiameters(other.ellipseDiameters());
setRotation(other.rotation());
setVelocity(other.velocity());
setState(target, other.state());
setPosition(target, other.position());
setScenePosition(target, other.scenePosition());
setGlobalPosition(target, other.globalPosition());
setEllipseDiameters(target, other.ellipseDiameters());
setRotation(target, other.rotation());
setVelocity(target, other.velocity());
}
/*! \internal

View File

@ -133,13 +133,7 @@ public:
d->pos = position;
}
void updateFrom(const QEventPoint &other);
static QMutableEventPoint *from(QEventPoint *me) { return static_cast<QMutableEventPoint *>(me); }
static QMutableEventPoint &from(QEventPoint &me) { return static_cast<QMutableEventPoint &>(me); }
static const QMutableEventPoint &constFrom(const QEventPoint &me) { return static_cast<const QMutableEventPoint &>(me); }
static void update(const QEventPoint &from, QEventPoint &to);
void detach() { detach(*this); }
static void detach(QEventPoint &p);

View File

@ -2849,7 +2849,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
for (auto &tempPt : e->points) {
// update state
auto epd = devPriv->pointById(tempPt.id());
auto &mut = QMutableEventPoint::from(epd->eventPoint);
auto &ep = epd->eventPoint;
epd->eventPoint.setAccepted(false);
switch (tempPt.state()) {
case QEventPoint::State::Pressed:
@ -2859,19 +2859,21 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// If the QPA event didn't tell us which window, find the one under the touchpoint position.
if (!window)
window = QGuiApplication::topLevelAt(tempPt.globalPosition().toPoint());
mut.setWindow(window);
QMutableEventPoint::setWindow(ep, window);
break;
case QEventPoint::State::Released:
if (Q_UNLIKELY(!window.isNull() && window != mut.window()))
qCWarning(lcPtrDispatch) << "delivering touch release to same window" << mut.window() << "not" << window.data();
window = mut.window();
if (Q_UNLIKELY(!window.isNull() && window != QMutableEventPoint::window(ep)))
qCWarning(lcPtrDispatch) << "delivering touch release to same window"
<< QMutableEventPoint::window(ep) << "not" << window.data();
window = QMutableEventPoint::window(ep);
break;
default: // update or stationary
if (Q_UNLIKELY(!window.isNull() && window != mut.window()))
qCWarning(lcPtrDispatch) << "delivering touch update to same window" << mut.window() << "not" << window.data();
window = mut.window();
if (Q_UNLIKELY(!window.isNull() && window != QMutableEventPoint::window(ep)))
qCWarning(lcPtrDispatch) << "delivering touch update to same window"
<< QMutableEventPoint::window(ep) << "not" << window.data();
window = QMutableEventPoint::window(ep);
break;
}
// If we somehow still don't have a window, we can't deliver this touchpoint. (should never happen)
@ -2879,30 +2881,30 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
qCWarning(lcPtrDispatch) << "skipping" << &tempPt << ": no target window";
continue;
}
mut.updateFrom(tempPt);
QMutableEventPoint::update(tempPt, ep);
Q_ASSERT(window.data() != nullptr);
// make the *scene* position the same as the *global* position
mut.setScenePosition(tempPt.globalPosition());
QMutableEventPoint::setScenePosition(ep, tempPt.globalPosition());
// store the scene position as local position, for now
mut.setPosition(window->mapFromGlobal(tempPt.globalPosition()));
QMutableEventPoint::setPosition(ep, window->mapFromGlobal(tempPt.globalPosition()));
// setTimeStamp has side effects, so we do it last
mut.setTimestamp(e->timestamp);
QMutableEventPoint::setTimestamp(ep, e->timestamp);
// add the touchpoint to the event that will be delivered to the window
bool added = false;
for (QMutableTouchEvent &ev : touchEvents) {
if (ev.target() == window.data()) {
ev.addPoint(mut);
ev.addPoint(ep);
added = true;
break;
}
}
if (!added) {
QMutableTouchEvent mte(e->touchType, device, e->modifiers, {mut});
QMutableTouchEvent mte(e->touchType, device, e->modifiers, {ep});
mte.setTimestamp(e->timestamp);
mte.setTarget(window.data());
touchEvents.append(mte);