aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2021-12-09 08:06:18 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2021-12-10 06:51:59 +0100
commite58cb58b44a0381592cd0e6eb0da3d3d6f1c5ccc (patch)
tree27ce55d00f38360501842b6f06a647f0c93045a6 /src
parentaf356e3bc87f8029026d1eaa345f7197c0705ffa (diff)
Allow reparenting Pointer Handlers
[ChangeLog][Event Handlers] The parent property of any Pointer Handler is now settable. Fixes: QTBUG-84730 Task-number: QTBUG-85926 Task-number: QTBUG-17286 Change-Id: Id738dd783de1acfbef9b5be203025040b0913008 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp16
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h4
-rw-r--r--src/quick/items/qquickitem.cpp22
-rw-r--r--src/quick/items/qquickitem_p.h2
4 files changed, 39 insertions, 5 deletions
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 4777f31b4b..2f38fe8973 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcPointerHandlerDispatch, "qt.quick.handler.dispatch")
Q_LOGGING_CATEGORY(lcPointerHandlerGrab, "qt.quick.handler.grab")
Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active")
+Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent)
/*!
\qmltype PointerHandler
@@ -626,6 +627,20 @@ QQuickItem *QQuickPointerHandler::parentItem() const
return qmlobject_cast<QQuickItem *>(QObject::parent());
}
+void QQuickPointerHandler::setParentItem(QQuickItem *p)
+{
+ if (QObject::parent() == p)
+ return;
+
+ qCDebug(lcHandlerParent) << "reparenting handler" << this << ":" << parent() << "->" << p;
+ if (auto *oldParent = static_cast<QQuickItem *>(QObject::parent()))
+ QQuickItemPrivate::get(oldParent)->removePointerHandler(this);
+ setParent(p);
+ if (p)
+ QQuickItemPrivate::get(p)->addPointerHandler(this);
+ emit parentChanged();
+}
+
QQuickItem *QQuickPointerHandler::target() const
{
Q_D(const QQuickPointerHandler);
@@ -725,7 +740,6 @@ void QQuickPointerHandler::handlePointerEventImpl(QPointerEvent *event)
}
/*!
- \readonly
\qmlproperty Item QtQuick::PointerHandler::parent
The \l Item which is the scope of the handler; the Item in which it was declared.
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index 125c8eb401..3f1b02ef62 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -68,7 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
Q_PROPERTY(QQuickItem * target READ target WRITE setTarget NOTIFY targetChanged)
- Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT)
+ Q_PROPERTY(QQuickItem * parent READ parentItem WRITE setParentItem NOTIFY parentChanged)
Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged)
Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged)
Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION(2, 15))
@@ -110,6 +110,7 @@ public:
void setTarget(QQuickItem *target);
QQuickItem * parentItem() const;
+ void setParentItem(QQuickItem *p);
void handlePointerEvent(QPointerEvent *event);
@@ -142,6 +143,7 @@ Q_SIGNALS:
#if QT_CONFIG(cursor)
Q_REVISION(2, 15) void cursorShapeChanged();
#endif
+ Q_REVISION(6, 3) void parentChanged();
protected:
QQuickPointerHandler(QQuickPointerHandlerPrivate &dd, QQuickItem *parent);
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index e4b7e18ae5..67572c231d 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -7718,8 +7718,10 @@ void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
d->extra.setTag(d->extra.tag().setFlag(QQuickItemPrivate::LeftMouseButtonAccepted, buttons & Qt::LeftButton));
buttons &= ~Qt::LeftButton;
- if (buttons || d->extra.isAllocated())
- d->extra.value().acceptedMouseButtons = buttons;
+ if (buttons || d->extra.isAllocated()) {
+ d->extra.value().acceptedMouseButtonsWithoutHandlers = buttons;
+ d->extra.value().acceptedMouseButtons = d->extra->pointerHandlers.isEmpty() ? buttons : Qt::AllButtons;
+ }
}
/*!
@@ -8960,10 +8962,11 @@ bool QQuickItemPrivate::hasHoverHandlers() const
void QQuickItemPrivate::addPointerHandler(QQuickPointerHandler *h)
{
+ Q_ASSERT(h);
Q_Q(QQuickItem);
// Accept all buttons, and leave filtering to pointerEvent() and/or user JS,
// because there can be multiple handlers...
- q->setAcceptedMouseButtons(Qt::AllButtons);
+ extra.value().acceptedMouseButtons = Qt::AllButtons;
auto &handlers = extra.value().pointerHandlers;
if (!handlers.contains(h))
handlers.prepend(h);
@@ -8976,6 +8979,19 @@ void QQuickItemPrivate::addPointerHandler(QQuickPointerHandler *h)
}
}
+void QQuickItemPrivate::removePointerHandler(QQuickPointerHandler *h)
+{
+ Q_ASSERT(h);
+ Q_Q(QQuickItem);
+ auto &handlers = extra.value().pointerHandlers;
+ handlers.removeOne(h);
+ auto &res = extra.value().resourcesList;
+ res.removeOne(h);
+ QObject::disconnect(h, &QObject::destroyed, q, nullptr);
+ if (handlers.isEmpty())
+ extra.value().acceptedMouseButtons = extra.value().acceptedMouseButtonsWithoutHandlers;
+}
+
#if QT_CONFIG(quick_shadereffect)
QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
: m_item(item)
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 6be15c4f3a..933019b3c6 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -286,6 +286,7 @@ public:
bool hasPointerHandlers() const;
bool hasHoverHandlers() const;
virtual void addPointerHandler(QQuickPointerHandler *h);
+ virtual void removePointerHandler(QQuickPointerHandler *h);
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
@@ -430,6 +431,7 @@ public:
// extremely common to set acceptedMouseButtons to LeftButton, but very
// rare to use any of the other buttons.
Qt::MouseButtons acceptedMouseButtons;
+ Qt::MouseButtons acceptedMouseButtonsWithoutHandlers;
QQuickItem::TransformOrigin origin:5;
uint transparentForPositioner : 1;