diff options
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquickflickable_p_p.h | 3 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 56 | ||||
-rw-r--r-- | src/quick/items/qquicklistview_p.h | 2 |
4 files changed, 55 insertions, 16 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index f222a4a32e..9a68be4c49 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1424,7 +1424,7 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event) void QQuickFlickable::mousePressEvent(QMouseEvent *event) { Q_D(QQuickFlickable); - if (d->interactive) { + if (d->interactive && d->wantsPointerEvent(event)) { if (!d->pressed) d->handleMousePressEvent(event); event->accept(); @@ -1436,7 +1436,7 @@ void QQuickFlickable::mousePressEvent(QMouseEvent *event) void QQuickFlickable::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickFlickable); - if (d->interactive) { + if (d->interactive && d->wantsPointerEvent(event)) { d->handleMouseMoveEvent(event); event->accept(); } else { @@ -1447,7 +1447,7 @@ void QQuickFlickable::mouseMoveEvent(QMouseEvent *event) void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickFlickable); - if (d->interactive) { + if (d->interactive && d->wantsPointerEvent(event)) { if (d->delayedPressEvent) { d->replayDelayedPress(); @@ -1475,7 +1475,7 @@ void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event) void QQuickFlickable::wheelEvent(QWheelEvent *event) { Q_D(QQuickFlickable); - if (!d->interactive) { + if (!d->interactive || !d->wantsPointerEvent(event)) { QQuickItem::wheelEvent(event); return; } @@ -2445,7 +2445,7 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event) bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e) { Q_D(QQuickFlickable); - if (!isVisible() || !isEnabled() || !isInteractive()) { + if (!isVisible() || !isEnabled() || !isInteractive() || !d->wantsPointerEvent(e)) { d->cancelInteraction(); return QQuickItem::childMouseEventFilter(i, e); } diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 3f5f11effd..414c9c33d6 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -208,6 +208,9 @@ public: void addPointerHandler(QQuickPointerHandler *h) override; + // TODO Qt 6: QPointerEvent + virtual bool wantsPointerEvent(const QEvent *) { return true; } + public: QQuickItem *contentItem; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 9dd85ded19..0f9394f695 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -58,6 +58,8 @@ QT_BEGIN_NAMESPACE #define QML_FLICK_SNAPONETHRESHOLD 30 #endif +Q_LOGGING_CATEGORY(lcEvents, "qt.quick.listview.events") + class FxListItemSG; class QQuickListViewPrivate : public QQuickItemViewPrivate @@ -143,6 +145,9 @@ public: void fixupHeader(); void fixupHeaderCompleted(); + + bool wantsPointerEvent(const QEvent *event) override; + QQuickListView::Orientation orient; qreal visiblePos; qreal averageSize; @@ -179,6 +184,7 @@ public: bool correctFlick : 1; bool inFlickCorrection : 1; + bool wantedMousePress : 1; QQuickListViewPrivate() : orient(QQuickListView::Vertical) @@ -192,7 +198,7 @@ public: , sectionCriteria(nullptr), currentSectionItem(nullptr), nextSectionItem(nullptr) , overshootDist(0.0), desiredViewportPosition(0.0), fixupHeaderPosition(0.0) , headerNeedsSeparateFixup(false), desiredHeaderVisible(false) - , correctFlick(false), inFlickCorrection(false) + , correctFlick(false), inFlickCorrection(false), wantedMousePress(false) { highlightMoveDuration = -1; //override default value set in base class } @@ -3819,20 +3825,52 @@ QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj) return new QQuickListViewAttached(obj); } -bool QQuickListView::contains(const QPointF &point) const +/*! \internal + Prevents clicking or dragging through floating headers (QTBUG-74046). +*/ +bool QQuickListViewPrivate::wantsPointerEvent(const QEvent *event) { - bool ret = QQuickItemView::contains(point); - // QTBUG-74046: if a mouse press "falls through" a floating header or footer, don't allow dragging the list from there - if (ret) { - if (auto header = headerItem()) { - if (headerPositioning() != QQuickListView::InlineHeader && header->contains(mapToItem(header, point))) + Q_Q(const QQuickListView); + bool ret = true; + + QPointF pos; + // TODO switch not needed in Qt 6: use points().first().position() + switch (event->type()) { + case QEvent::Wheel: + pos = static_cast<const QWheelEvent *>(event)->position(); + break; + case QEvent::MouseButtonPress: + pos = static_cast<const QMouseEvent *>(event)->localPos(); + break; + default: + break; + } + + if (!pos.isNull()) { + if (auto header = q->headerItem()) { + if (q->headerPositioning() != QQuickListView::InlineHeader && + header->contains(q->mapToItem(header, pos))) ret = false; } - if (auto footer = footerItem()) { - if (footerPositioning() != QQuickListView::InlineFooter && footer->contains(mapToItem(footer, point))) + if (auto footer = q->footerItem()) { + if (q->footerPositioning() != QQuickListView::InlineFooter && + footer->contains(q->mapToItem(footer, pos))) ret = false; } } + + switch (event->type()) { + case QEvent::MouseButtonPress: + wantedMousePress = ret; + break; + case QEvent::MouseMove: + ret = wantedMousePress; + break; + default: + break; + } + + qCDebug(lcEvents) << q << (ret ? "WANTS" : "DOESN'T want") << event; return ret; } diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h index be21b93155..1c72a10190 100644 --- a/src/quick/items/qquicklistview_p.h +++ b/src/quick/items/qquicklistview_p.h @@ -179,8 +179,6 @@ public: static QQuickListViewAttached *qmlAttachedProperties(QObject *); - bool contains(const QPointF &point) const override; - public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); |