--- qtdeclarative/src/quick/items/qquickwindow.cpp Thu Nov 30 17:10:22 2017 +++ qtdeclarative/src/quick/items/qquickwindow.cpp Wed Apr 11 21:53:11 2018 @@ -2479,6 +2479,7 @@ bool isTouchEvent = (event->asPointerTouchEvent() != nullptr); for (int i = 0; i < pointCount; ++i) { auto point = event->point(i); + if (!point) continue; point->setAccepted(false); // because otherwise touchEventForItem will ignore it if (point->grabberPointerHandler() && point->state() == QQuickEventPoint::Released) point->setGrabberPointerHandler(nullptr, true); @@ -2493,8 +2494,10 @@ for (QQuickItem *item : targetItems) { if (!handlersOnly && sendFilteredPointerEvent(event, item)) { if (event->isAccepted()) { - for (int i = 0; i < event->pointCount(); ++i) - event->point(i)->setAccepted(); + for (int i = 0; i < event->pointCount(); ++i) { + if (auto p = event->point(i)) + p->setAccepted(); + } return true; } skipDelivery.append(item); @@ -2540,7 +2543,7 @@ auto event = pointerEvent->asPointerMouseEvent(); if (event && item->acceptedMouseButtons() & event->button()) { auto point = event->point(0); - if (point->isAccepted()) + if (!point || point->isAccepted()) return; // The only reason to already have a mouse grabber here is // synthetic events - flickable sends one when setPressDelay is used. @@ -2595,6 +2598,7 @@ bool isPressOrRelease = pointerEvent->isPressEvent() || pointerEvent->isReleaseEvent(); for (auto point: qAsConst(touchEvent->touchPoints())) { auto pointerEventPoint = ptEvent->pointById(point.id()); + if (!pointerEventPoint) continue; pointerEventPoint->setAccepted(); if (isPressOrRelease) pointerEventPoint->setGrabberItem(item); --- qtdeclarative/src/quick/items/qquickevents.cpp Thu Nov 30 17:10:22 2017 +++ qtdeclarative/src/quick/items/qquickevents.cpp Wed Apr 11 21:03:00 2018 @@ -1529,17 +1529,32 @@ bool QQuickPointerTouchEvent::isPressEvent() const { - return static_cast(m_event)->touchPointStates() & Qt::TouchPointPressed; + QTouchEvent *touchEvent = Q_NULLPTR; + if (!m_event || !(touchEvent = dynamic_cast(m_event))) { + qWarning() << __FUNCTION__ << "Invalid touch event!" << m_event; + return false; + } + return touchEvent->touchPointStates() & Qt::TouchPointPressed; } bool QQuickPointerTouchEvent::isUpdateEvent() const { - return static_cast(m_event)->touchPointStates() & (Qt::TouchPointMoved | Qt::TouchPointStationary); + QTouchEvent *touchEvent = Q_NULLPTR; + if (!m_event || !(touchEvent = dynamic_cast(m_event))) { + qWarning() << __FUNCTION__ << "Invalid touch event!" << m_event; + return false; + } + return touchEvent->touchPointStates() & (Qt::TouchPointMoved | Qt::TouchPointStationary); } bool QQuickPointerTouchEvent::isReleaseEvent() const { - return static_cast(m_event)->touchPointStates() & Qt::TouchPointReleased; + QTouchEvent *touchEvent = Q_NULLPTR; + if (!m_event || !(touchEvent = dynamic_cast(m_event))) { + qWarning() << __FUNCTION__ << "Invalid touch event!" << m_event; + return false; + } + return touchEvent->touchPointStates() & Qt::TouchPointReleased; } QVector QQuickPointerEvent::unacceptedPressedPointScenePositions() const --- qtdeclarative/src/quick/items/qquickevents_p_p.h Thu Nov 30 17:10:22 2017 +++ qtdeclarative/src/quick/items/qquickevents_p_p.h Wed Apr 11 21:42:00 2018 @@ -456,8 +456,8 @@ bool isDoubleClickEvent() const override; bool isUpdateEvent() const override; bool isReleaseEvent() const override; - QQuickPointerMouseEvent *asPointerMouseEvent() override { return this; } - const QQuickPointerMouseEvent *asPointerMouseEvent() const override { return this; } + QQuickPointerMouseEvent *asPointerMouseEvent() override { return m_event && dynamic_cast(m_event)? this : nullptr; } + const QQuickPointerMouseEvent *asPointerMouseEvent() const override { return m_event && dynamic_cast(m_event)? this : nullptr; } int pointCount() const override { return 1; } QQuickEventPoint *point(int i) const override; QQuickEventPoint *pointById(int pointId) const override; @@ -491,8 +491,8 @@ bool isPressEvent() const override; bool isUpdateEvent() const override; bool isReleaseEvent() const override; - QQuickPointerTouchEvent *asPointerTouchEvent() override { return this; } - const QQuickPointerTouchEvent *asPointerTouchEvent() const override { return this; } + QQuickPointerTouchEvent *asPointerTouchEvent() override { return m_event && dynamic_cast(m_event)? this : nullptr; } + const QQuickPointerTouchEvent *asPointerTouchEvent() const override { return m_event && dynamic_cast(m_event)? this : nullptr; } int pointCount() const override { return m_pointCount; } QQuickEventPoint *point(int i) const override; QQuickEventPoint *pointById(int pointId) const override;