summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2016-11-22 13:45:45 +0200
committerAntti Määttä <antti.maatta@qt.io>2017-01-27 12:06:52 +0000
commit1e04bb374fafe4a00d0fd4b8d5a0c5588781f888 (patch)
tree9422c8d25b1d55b0e5bdd9d92f3917f7e4fd4efd
parent7d1ba2e0676241634f38d907b10ae6e2bd2c6f0a (diff)
Move event forwarding to frontend
Move the event forwarding to frontend so that the target object destruction can be handled properly. Change-Id: I6bdee731760cee69334aad7ca39f0dd16c44a471 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/picking/eventforward.cpp41
-rw-r--r--src/render/picking/eventforward_p.h4
-rw-r--r--src/render/picking/picking.pri6
-rw-r--r--src/render/picking/posteventstofrontend.cpp74
-rw-r--r--src/render/picking/posteventstofrontend_p.h81
-rw-r--r--src/render/picking/qeventforward.cpp31
-rw-r--r--src/render/picking/qeventforward.h4
-rw-r--r--src/render/picking/qeventforward_p.h1
8 files changed, 217 insertions, 25 deletions
diff --git a/src/render/picking/eventforward.cpp b/src/render/picking/eventforward.cpp
index 132e022ce..0216542bd 100644
--- a/src/render/picking/eventforward.cpp
+++ b/src/render/picking/eventforward.cpp
@@ -40,6 +40,7 @@
#include <private/qeventforward_p.h>
#include <private/eventforward_p.h>
+#include <private/posteventstofrontend_p.h>
#include <QtGui/qevent.h>
#include <QtCore/qcoreapplication.h>
@@ -51,7 +52,7 @@ namespace Qt3DRender {
namespace Render {
EventForward::EventForward()
- : m_target(nullptr)
+ : BackendNode(QBackendNode::ReadWrite)
, m_forwardMouseEvents(false)
, m_forwardKeyboardEvents(false)
, m_focus(false)
@@ -67,7 +68,6 @@ EventForward::~EventForward()
void EventForward::cleanup()
{
setEnabled(false);
- m_target = nullptr;
m_coordinateAttribute = "";
m_coordinateTransform.setToIdentity();
m_forwardMouseEvents = false;
@@ -75,11 +75,6 @@ void EventForward::cleanup()
m_focus = false;
}
-QObject *EventForward::target() const
-{
- return m_target;
-}
-
QString EventForward::coordinateAttribute() const
{
return m_coordinateAttribute;
@@ -105,11 +100,6 @@ bool EventForward::focus() const
return m_focus;
}
-void EventForward::setTarget(QObject *target)
-{
- m_target = target;
-}
-
void EventForward::setCoordinateTransform(const QMatrix4x4 &transform)
{
m_coordinateTransform = transform;
@@ -139,7 +129,6 @@ void EventForward::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr
{
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QEventForwardData>>(change);
const auto &data = typedChange->data;
- setTarget(data.target);
setCoordinateAttribute(data.coordinateAttribute);
setCoordinateTransform(data.coordinateTransform);
setForwardMouseEvents(data.forwardMouseEvents);
@@ -153,9 +142,7 @@ void EventForward::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
const Qt3DCore::QPropertyUpdatedChangePtr propertyChange
= qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("target"))
- setTarget(propertyChange->value().value<QObject*>());
- else if (propertyChange->propertyName() == QByteArrayLiteral("coordinateTransform"))
+ if (propertyChange->propertyName() == QByteArrayLiteral("coordinateTransform"))
setCoordinateTransform(propertyChange->value().value<QMatrix4x4>());
else if (propertyChange->propertyName() == QByteArrayLiteral("coordinateAttribute"))
setCoordinateAttribute(propertyChange->value().toString());
@@ -177,16 +164,30 @@ void EventForward::forward(const QMouseEvent &event, const QVector4D &coordinate
QMouseEvent *mouseEvent = new QMouseEvent(event.type(), local, local, local, event.button(),
event.buttons(), event.modifiers(),
Qt::MouseEventSynthesizedByApplication);
- QCoreApplication::postEvent(m_target, mouseEvent);
+
+ PostEventsToFrontendPtr events = PostEventsToFrontendPtr::create(mouseEvent);
+
+ auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
+ e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
+ e->setPropertyName("events");
+ e->setValue(QVariant::fromValue(events));
+ notifyObservers(e);
}
-void EventForward::forward(const QList<QKeyEvent> &events)
+void EventForward::forward(const QList<QKeyEvent> &keyEvents)
{
- for (const QKeyEvent &e : events) {
+ QVector<QEvent *> eventsToSend;
+ for (const QKeyEvent &e : keyEvents) {
QKeyEvent *keyEvent = new QKeyEvent(e.type(), e.key(), e.modifiers(), e.nativeScanCode(),
e.nativeVirtualKey(), e.nativeModifiers());
- QCoreApplication::postEvent(m_target, keyEvent);
+ eventsToSend.append(keyEvent);
}
+ PostEventsToFrontendPtr events = PostEventsToFrontendPtr::create(eventsToSend);
+ auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
+ e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
+ e->setPropertyName("events");
+ e->setValue(QVariant::fromValue(events));
+ notifyObservers(e);
}
} // Render
diff --git a/src/render/picking/eventforward_p.h b/src/render/picking/eventforward_p.h
index e090ba5e4..663298e40 100644
--- a/src/render/picking/eventforward_p.h
+++ b/src/render/picking/eventforward_p.h
@@ -69,7 +69,6 @@ public:
void cleanup();
- QObject *target() const;
QString coordinateAttribute() const;
QMatrix4x4 coordinateTransform() const;
bool forwardMouseEvents() const;
@@ -86,12 +85,11 @@ public:
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL;
void forward(const QMouseEvent &event, const QVector4D &coordinate);
- void forward(const QList<QKeyEvent> &events);
+ void forward(const QList<QKeyEvent> &keyEvents);
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL;
- QObject *m_target;
QString m_coordinateAttribute;
QMatrix4x4 m_coordinateTransform;
bool m_forwardMouseEvents;
diff --git a/src/render/picking/picking.pri b/src/render/picking/picking.pri
index e581a8f8a..c2eb8f50b 100644
--- a/src/render/picking/picking.pri
+++ b/src/render/picking/picking.pri
@@ -10,7 +10,8 @@ HEADERS += \
$$PWD/qobjectpicker_p.h \
$$PWD/qeventforward.h \
$$PWD/qeventforward_p.h \
- $$PWD/eventforward_p.h
+ $$PWD/eventforward_p.h \
+ $$PWD/posteventstofrontend_p.h
SOURCES += \
$$PWD/qobjectpicker.cpp \
@@ -19,4 +20,5 @@ SOURCES += \
$$PWD/objectpicker.cpp \
$$PWD/pickeventfilter.cpp \
$$PWD/qeventforward.cpp \
- $$PWD/eventforward.cpp
+ $$PWD/eventforward.cpp \
+ $$PWD/posteventstofrontend.cpp
diff --git a/src/render/picking/posteventstofrontend.cpp b/src/render/picking/posteventstofrontend.cpp
new file mode 100644
index 000000000..51f986902
--- /dev/null
+++ b/src/render/picking/posteventstofrontend.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "posteventstofrontend_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+PostEventsToFrontend::PostEventsToFrontend()
+ : QObject()
+{
+
+}
+
+PostEventsToFrontend::PostEventsToFrontend(QEvent *event)
+ : QObject()
+{
+ m_events.append(event);
+}
+
+PostEventsToFrontend::PostEventsToFrontend(const QVector<QEvent *> &events)
+ : QObject()
+{
+ m_events = events;
+}
+
+PostEventsToFrontend::~PostEventsToFrontend()
+{
+ for (QEvent *e : m_events)
+ delete e;
+}
+
+QVector<QEvent *> &PostEventsToFrontend::events()
+{
+ return m_events;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/render/picking/posteventstofrontend_p.h b/src/render/picking/posteventstofrontend_p.h
new file mode 100644
index 000000000..5dd29b047
--- /dev/null
+++ b/src/render/picking/posteventstofrontend_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DRENDER_POSTEVENTSTOFRONTEND_P_H
+#define QT3DRENDER_POSTEVENTSTOFRONTEND_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qevent.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qsharedpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class Q_AUTOTEST_EXPORT PostEventsToFrontend : public QObject
+{
+ Q_OBJECT
+public:
+ PostEventsToFrontend();
+ PostEventsToFrontend(QEvent *event);
+ PostEventsToFrontend(const QVector<QEvent *> &events);
+ ~PostEventsToFrontend();
+
+ QVector<QEvent *> &events();
+private:
+ QVector<QEvent *> m_events;
+};
+
+typedef QSharedPointer<PostEventsToFrontend> PostEventsToFrontendPtr;
+
+} // Qt3DRender
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Qt3DRender::PostEventsToFrontend*)
+
+#endif // QT3DRENDER_POSTEVENTSTOFRONTEND_P_H
diff --git a/src/render/picking/qeventforward.cpp b/src/render/picking/qeventforward.cpp
index 8aa22e276..08546fabd 100644
--- a/src/render/picking/qeventforward.cpp
+++ b/src/render/picking/qeventforward.cpp
@@ -36,8 +36,12 @@
#include "qeventforward.h"
#include "qeventforward_p.h"
+#include "posteventstofrontend_p.h"
#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@@ -148,11 +152,24 @@ QObject *QEventForward::target() const
return d->m_target;
}
+void QEventForward::targetDestroyed(QObject *target)
+{
+ Q_D(QEventForward);
+ Q_ASSERT(target == d->m_target);
+ setTarget(nullptr);
+}
+
void QEventForward::setTarget(QObject *target)
{
Q_D(QEventForward);
if (target != d->m_target) {
+ if (d->m_target != nullptr)
+ QObject::disconnect(d->m_destructionConnection);
d->m_target = target;
+ if (d->m_target) {
+ d->m_destructionConnection = QObject::connect(target, &QObject::destroyed,
+ this, &QEventForward::targetDestroyed);
+ }
emit targetChanged(target);
}
}
@@ -249,6 +266,20 @@ Qt3DCore::QNodeCreatedChangeBasePtr QEventForward::createNodeCreationChange() co
return creationChange;
}
+void QEventForward::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
+{
+ Q_D(QEventForward);
+ Qt3DCore::QPropertyUpdatedChangePtr e
+ = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
+ if (e->type() == Qt3DCore::PropertyUpdated && d->m_target != nullptr) {
+ if (e->propertyName() == QByteArrayLiteral("events")) {
+ PostEventsToFrontendPtr postedEvents = e->value().value<PostEventsToFrontendPtr>();
+ for (QEvent *event : postedEvents->events())
+ QCoreApplication::sendEvent(d->m_target, event);
+ }
+ }
+}
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/picking/qeventforward.h b/src/render/picking/qeventforward.h
index 28659606b..ee8100318 100644
--- a/src/render/picking/qeventforward.h
+++ b/src/render/picking/qeventforward.h
@@ -87,9 +87,13 @@ Q_SIGNALS:
void forwardKeyboardEventsChanged(bool forward);
void focusChanged(bool focus);
+protected:
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE;
+
private:
Q_DECLARE_PRIVATE(QEventForward)
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+ void targetDestroyed(QObject *target);
};
} // Qt3DRender
diff --git a/src/render/picking/qeventforward_p.h b/src/render/picking/qeventforward_p.h
index 4aa6834df..c087bc8f5 100644
--- a/src/render/picking/qeventforward_p.h
+++ b/src/render/picking/qeventforward_p.h
@@ -81,6 +81,7 @@ public:
bool m_forwardMouseEvents;
bool m_forwardKeyboardEvents;
bool m_focus;
+ QMetaObject::Connection m_destructionConnection;
};
struct QEventForwardData