aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickflickable.cpp10
-rw-r--r--src/quick/items/qquickflickable_p_p.h3
-rw-r--r--src/quick/items/qquicklistview.cpp56
-rw-r--r--src/quick/items/qquicklistview_p.h2
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();