diff options
author | Andy Shaw <andy.shaw@qt.io> | 2019-04-14 10:43:57 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-04-16 12:53:29 +0000 |
commit | a54eb316af7921ff77d4419c8b11b31f8e6fac7b (patch) | |
tree | 59752ad0e9872e2b36cd7be09d8c431d1aa699e8 | |
parent | 1edf84eff083eb5412b4c5c7cd3bd8166f15f61f (diff) | |
download | qtquickcontrols-a54eb316af7921ff77d4419c8b11b31f8e6fac7b.tar.gz |
Create the decoration component when it is needed
If multiple QQmlEngines are created and use a Dialog,
initalizeEngine will be called more than once and therefore recreates
the QQuickAbstractDialog::m_decorationComponent without deleting the
original. Therefore we keep the decoration component url instead, and
create the decoration component on demand. This ensures that
it keeps the component relevant for the QQmlEngine and stops the
memory leak from before as well.
Fixes: QTBUG-75149
Change-Id: Ic79103f42d092d39b46868a45b4099ddc6edf9db
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/dialogs/plugin.cpp | 10 | ||||
-rw-r--r-- | src/dialogs/qquickabstractdialog.cpp | 6 | ||||
-rw-r--r-- | src/dialogs/qquickabstractdialog_p.h | 3 |
3 files changed, 8 insertions, 11 deletions
diff --git a/src/dialogs/plugin.cpp b/src/dialogs/plugin.cpp index 8c10786f..b31d233e 100644 --- a/src/dialogs/plugin.cpp +++ b/src/dialogs/plugin.cpp @@ -40,6 +40,7 @@ #include <QtQml/qqml.h> #include <QtQml/qqmlextensionplugin.h> #include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlengine.h> #include "qquickmessagedialog_p.h" #include "qquickabstractmessagedialog_p.h" #include "qquickdialogassets_p.h" @@ -87,12 +88,6 @@ class QtQuick2DialogsPlugin : public QQmlExtensionPlugin public: QtQuick2DialogsPlugin() : QQmlExtensionPlugin(), m_useResources(true) { } - virtual void initializeEngine(QQmlEngine *engine, const char * uri) { - qCDebug(lcRegistration) << uri << m_decorationComponentUrl; - QQuickAbstractDialog::m_decorationComponent = - new QQmlComponent(engine, m_decorationComponentUrl, QQmlComponent::Asynchronous); - } - virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs")); bool hasTopLevelWindows = QGuiApplicationPrivate::platformIntegration()-> @@ -114,7 +109,7 @@ public: m_useResources = false; #endif #endif - m_decorationComponentUrl = m_useResources ? + QQuickAbstractDialog::m_decorationComponentUrl = m_useResources ? QUrl("qrc:/QtQuick/Dialogs/qml/DefaultWindowDecoration.qml") : #ifndef QT_STATIC QUrl::fromLocalFile(qmlDir.filePath(QString("qml/DefaultWindowDecoration.qml"))); @@ -256,7 +251,6 @@ protected: qmlRegisterType(dialogQmlPath, uri, versionMajor, versionMinor, qmlName); } - QUrl m_decorationComponentUrl; bool m_useResources; }; diff --git a/src/dialogs/qquickabstractdialog.cpp b/src/dialogs/qquickabstractdialog.cpp index e00c17a1..e71948d1 100644 --- a/src/dialogs/qquickabstractdialog.cpp +++ b/src/dialogs/qquickabstractdialog.cpp @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcWindow, "qt.quick.dialogs.window") -QQmlComponent *QQuickAbstractDialog::m_decorationComponent(0); +QUrl QQuickAbstractDialog::m_decorationComponentUrl = QUrl(); QQuickAbstractDialog::QQuickAbstractDialog(QObject *parent) : QObject(parent) @@ -151,6 +151,8 @@ void QQuickAbstractDialog::setVisible(bool v) // If the platform does not support multiple windows, but the dialog is // implemented as an Item, then try to decorate it as a fake window and make it visible. if (!m_windowDecoration) { + if (!m_decorationComponent) + m_decorationComponent = new QQmlComponent(qmlEngine(this), m_decorationComponentUrl, QQmlComponent::Asynchronous, this); if (m_decorationComponent) { if (m_decorationComponent->isLoading()) connect(m_decorationComponent, SIGNAL(statusChanged(QQmlComponent::Status)), @@ -232,7 +234,7 @@ void QQuickAbstractDialog::decorationLoaded() "cannot be used as a window decoration because it's not an Item"; delete decoration; delete m_decorationComponent; - m_decorationComponent = 0; + m_decorationComponent = nullptr; } } // Window decoration wasn't possible, so just reparent it into the scene diff --git a/src/dialogs/qquickabstractdialog_p.h b/src/dialogs/qquickabstractdialog_p.h index 54dbaace..a861739b 100644 --- a/src/dialogs/qquickabstractdialog_p.h +++ b/src/dialogs/qquickabstractdialog_p.h @@ -167,7 +167,8 @@ protected: // variables and methods for pure-QML implementations only bool m_visibleChangedConnected; bool m_dialogHelperInUse; - static QQmlComponent *m_decorationComponent; + QQmlComponent *m_decorationComponent = nullptr; + static QUrl m_decorationComponentUrl; friend class QtQuick2DialogsPlugin; |