From d1a43e4a37cb6bbe0dfcbacd4ce975b0ce0090f0 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 10 Aug 2020 13:13:38 +0200 Subject: Quick: Make sure the module initialization runs in static builds We need to keep a reference to the module initialization function somewhere in order to prevent the linker from removing it. In order to avoid further littering of the namespace, the QQuick_initializeProviders function is transformed to cover all of the initialization. Task-number: QTBUG-85693 Change-Id: Ie93e5abd1dfb5a425b87c70d8ec6327bb68880cb Reviewed-by: Fabian Kosmale Reviewed-by: Shawn Rutledge --- src/imports/qtquick2/plugin.cpp | 2 + src/quick/.prev_CMakeLists.txt | 1 - src/quick/CMakeLists.txt | 1 - src/quick/qtquick2.cpp | 197 ---------------------------------------- src/quick/qtquickglobal_p.h | 2 +- src/quick/quick.pro | 2 - src/quick/util/qquickglobal.cpp | 143 ++++++++++++++++++++++++++++- 7 files changed, 145 insertions(+), 203 deletions(-) delete mode 100644 src/quick/qtquick2.cpp (limited to 'src') diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp index 414d9e29f5..8ab49c882e 100644 --- a/src/imports/qtquick2/plugin.cpp +++ b/src/imports/qtquick2/plugin.cpp @@ -50,7 +50,9 @@ public: QtQuick2Plugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) { volatile auto registration = &qml_register_types_QtQuick; + volatile auto initialization = &QQuick_initializeModule; Q_UNUSED(registration); + Q_UNUSED(initialization); } }; diff --git a/src/quick/.prev_CMakeLists.txt b/src/quick/.prev_CMakeLists.txt index 0faa2397ff..d9d099cce4 100644 --- a/src/quick/.prev_CMakeLists.txt +++ b/src/quick/.prev_CMakeLists.txt @@ -89,7 +89,6 @@ qt_add_module(Quick items/qquickwindowattached.cpp items/qquickwindowattached_p.h items/qquickwindowmodule.cpp items/qquickwindowmodule_p.h items/qquickwindowmodule_p_p.h - qtquick2.cpp qtquickglobal.h qtquickglobal_p.h scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h scenegraph/adaptations/software/qsgsoftwareadaptation.cpp scenegraph/adaptations/software/qsgsoftwareadaptation_p.h diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index 412f13e808..67b6969467 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -89,7 +89,6 @@ qt_add_module(Quick items/qquickwindowattached.cpp items/qquickwindowattached_p.h items/qquickwindowmodule.cpp items/qquickwindowmodule_p.h items/qquickwindowmodule_p_p.h - qtquick2.cpp qtquickglobal.h qtquickglobal_p.h scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h scenegraph/adaptations/software/qsgsoftwareadaptation.cpp scenegraph/adaptations/software/qsgsoftwareadaptation_p.h diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp deleted file mode 100644 index cc5c3d3826..0000000000 --- a/src/quick/qtquick2.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -#if QT_CONFIG(qml_debug) - -class QQmlQtQuick2DebugStatesDelegate : public QQmlDebugStatesDelegate -{ -public: - QQmlQtQuick2DebugStatesDelegate(); - ~QQmlQtQuick2DebugStatesDelegate(); - void buildStatesList(bool cleanList, const QList > &instances) override; - void updateBinding(QQmlContext *context, - const QQmlProperty &property, - const QVariant &expression, bool isLiteralValue, - const QString &fileName, int line, int column, - bool *isBaseState) override; - bool setBindingForInvalidProperty(QObject *object, - const QString &propertyName, - const QVariant &expression, - bool isLiteralValue) override; - void resetBindingForInvalidProperty(QObject *object, - const QString &propertyName) override; - -private: - void buildStatesList(QObject *obj); - - QList > m_allStates; -}; - -QQmlQtQuick2DebugStatesDelegate::QQmlQtQuick2DebugStatesDelegate() -{ -} - -QQmlQtQuick2DebugStatesDelegate::~QQmlQtQuick2DebugStatesDelegate() -{ -} - -void QQmlQtQuick2DebugStatesDelegate::buildStatesList(bool cleanList, - const QList > &instances) -{ - if (cleanList) - m_allStates.clear(); - - //only root context has all instances - for (int ii = 0; ii < instances.count(); ++ii) { - buildStatesList(instances.at(ii)); - } -} - -void QQmlQtQuick2DebugStatesDelegate::buildStatesList(QObject *obj) -{ - if (QQuickState *state = qobject_cast(obj)) { - m_allStates.append(state); - } - - QObjectList children = obj->children(); - for (int ii = 0; ii < children.count(); ++ii) { - buildStatesList(children.at(ii)); - } -} - -void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, - const QQmlProperty &property, - const QVariant &expression, bool isLiteralValue, - const QString &fileName, int line, int column, - bool *inBaseState) -{ - Q_UNUSED(column); - typedef QPointer QuickStatePointer; - QObject *object = property.object(); - QString propertyName = property.name(); - for (const QuickStatePointer& statePointer : qAsConst(m_allStates)) { - if (QQuickState *state = statePointer.data()) { - // here we assume that the revert list on itself defines the base state - if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { - *inBaseState = false; - - QQmlBinding *newBinding = nullptr; - if (!isLiteralValue) { - newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, - expression.toString(), object, - QQmlContextData::get(context), fileName, - line); - newBinding->setTarget(property); - } - - state->changeBindingInRevertList(object, propertyName, newBinding); - - if (isLiteralValue) - state->changeValueInRevertList(object, propertyName, expression); - } - } - } -} - -bool QQmlQtQuick2DebugStatesDelegate::setBindingForInvalidProperty(QObject *object, - const QString &propertyName, - const QVariant &expression, - bool isLiteralValue) -{ - if (QQuickPropertyChanges *propertyChanges = qobject_cast(object)) { - if (isLiteralValue) - propertyChanges->changeValue(propertyName, expression); - else - propertyChanges->changeExpression(propertyName, expression.toString()); - return true; - } else { - return false; - } -} - -void QQmlQtQuick2DebugStatesDelegate::resetBindingForInvalidProperty(QObject *object, const QString &propertyName) -{ - if (QQuickPropertyChanges *propertyChanges = qobject_cast(object)) { - propertyChanges->removeProperty(propertyName); - } -} - -static QQmlDebugStatesDelegate *statesDelegateFactory() -{ - return new QQmlQtQuick2DebugStatesDelegate; -} - -#endif // QT_CONFIG(qml_debug) - -static void defineQtQuickModule() -{ - QQuick_initializeProviders(); - QQuickItemsModule::defineModule(); - -#if QT_CONFIG(accessibility) - QAccessible::installFactory(&qQuickAccessibleFactory); -#endif - -#if QT_CONFIG(qml_debug) - QQmlEngineDebugService::setStatesDelegateFactory(statesDelegateFactory); -#endif -} - -Q_CONSTRUCTOR_FUNCTION(defineQtQuickModule) - -QT_END_NAMESPACE - diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h index 142e29ea83..e527428808 100644 --- a/src/quick/qtquickglobal_p.h +++ b/src/quick/qtquickglobal_p.h @@ -65,7 +65,7 @@ void Q_QUICK_PRIVATE_EXPORT qml_register_types_QtQuick(); QT_BEGIN_NAMESPACE -void QQuick_initializeProviders(); +void Q_QUICK_PRIVATE_EXPORT QQuick_initializeModule(); Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH) Q_DECLARE_LOGGING_CATEGORY(DBG_MOUSE) diff --git a/src/quick/quick.pro b/src/quick/quick.pro index 6eb6575326..1e2c0360c2 100644 --- a/src/quick/quick.pro +++ b/src/quick/quick.pro @@ -46,8 +46,6 @@ HEADERS += \ qtquickglobal.h \ qtquickglobal_p.h -SOURCES += qtquick2.cpp - # To make #include "qquickcontext2d_jsclass.cpp" work INCLUDEPATH += $$PWD diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 9d97280061..817977eb3b 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -40,12 +40,19 @@ #include #include +#include +#include +#include +#include #include #include #include #include +#include +#include +#include #include #include #include @@ -57,6 +64,128 @@ QT_BEGIN_NAMESPACE +#if QT_CONFIG(qml_debug) + +class QQmlQtQuick2DebugStatesDelegate : public QQmlDebugStatesDelegate +{ +public: + QQmlQtQuick2DebugStatesDelegate(); + ~QQmlQtQuick2DebugStatesDelegate(); + void buildStatesList(bool cleanList, const QList > &instances) override; + void updateBinding(QQmlContext *context, + const QQmlProperty &property, + const QVariant &expression, bool isLiteralValue, + const QString &fileName, int line, int column, + bool *isBaseState) override; + bool setBindingForInvalidProperty(QObject *object, + const QString &propertyName, + const QVariant &expression, + bool isLiteralValue) override; + void resetBindingForInvalidProperty(QObject *object, + const QString &propertyName) override; + +private: + void buildStatesList(QObject *obj); + + QList > m_allStates; +}; + +QQmlQtQuick2DebugStatesDelegate::QQmlQtQuick2DebugStatesDelegate() +{ +} + +QQmlQtQuick2DebugStatesDelegate::~QQmlQtQuick2DebugStatesDelegate() +{ +} + +void QQmlQtQuick2DebugStatesDelegate::buildStatesList(bool cleanList, + const QList > &instances) +{ + if (cleanList) + m_allStates.clear(); + + //only root context has all instances + for (int ii = 0; ii < instances.count(); ++ii) { + buildStatesList(instances.at(ii)); + } +} + +void QQmlQtQuick2DebugStatesDelegate::buildStatesList(QObject *obj) +{ + if (QQuickState *state = qobject_cast(obj)) { + m_allStates.append(state); + } + + QObjectList children = obj->children(); + for (int ii = 0; ii < children.count(); ++ii) { + buildStatesList(children.at(ii)); + } +} + +void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, + const QQmlProperty &property, + const QVariant &expression, bool isLiteralValue, + const QString &fileName, int line, int column, + bool *inBaseState) +{ + Q_UNUSED(column); + typedef QPointer QuickStatePointer; + QObject *object = property.object(); + QString propertyName = property.name(); + for (const QuickStatePointer& statePointer : qAsConst(m_allStates)) { + if (QQuickState *state = statePointer.data()) { + // here we assume that the revert list on itself defines the base state + if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { + *inBaseState = false; + + QQmlBinding *newBinding = nullptr; + if (!isLiteralValue) { + newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, + expression.toString(), object, + QQmlContextData::get(context), fileName, + line); + newBinding->setTarget(property); + } + + state->changeBindingInRevertList(object, propertyName, newBinding); + + if (isLiteralValue) + state->changeValueInRevertList(object, propertyName, expression); + } + } + } +} + +bool QQmlQtQuick2DebugStatesDelegate::setBindingForInvalidProperty(QObject *object, + const QString &propertyName, + const QVariant &expression, + bool isLiteralValue) +{ + if (QQuickPropertyChanges *propertyChanges = qobject_cast(object)) { + if (isLiteralValue) + propertyChanges->changeValue(propertyName, expression); + else + propertyChanges->changeExpression(propertyName, expression.toString()); + return true; + } else { + return false; + } +} + +void QQmlQtQuick2DebugStatesDelegate::resetBindingForInvalidProperty(QObject *object, const QString &propertyName) +{ + if (QQuickPropertyChanges *propertyChanges = qobject_cast(object)) { + propertyChanges->removeProperty(propertyName); + } +} + +static QQmlDebugStatesDelegate *statesDelegateFactory() +{ + return new QQmlQtQuick2DebugStatesDelegate; +} + +#endif // QT_CONFIG(qml_debug) + class QQuickColorProvider : public QQmlColorProvider { public: @@ -919,11 +1048,23 @@ static QQuickGuiProvider *getGuiProvider() return &guiProvider; } -void QQuick_initializeProviders() +void QQuick_initializeModule() { QQml_addValueTypeProvider(getValueTypeProvider()); QQml_setColorProvider(getColorProvider()); QQml_setGuiProvider(getGuiProvider()); + + QQuickItemsModule::defineModule(); + +#if QT_CONFIG(accessibility) + QAccessible::installFactory(&qQuickAccessibleFactory); +#endif + +#if QT_CONFIG(qml_debug) + QQmlEngineDebugService::setStatesDelegateFactory(statesDelegateFactory); +#endif } +Q_CONSTRUCTOR_FUNCTION(QQuick_initializeModule) + QT_END_NAMESPACE -- cgit v1.2.3