diff options
Diffstat (limited to 'src')
37 files changed, 341 insertions, 145 deletions
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp index 26c6d4032f..44f0a49d76 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp @@ -255,7 +255,8 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path) \list \li \c fileName \li \c filePath - \li \c fileURL (since Qt 5.2) + \li \c fileURL (since Qt 5.2; deprecated since Qt 5.15) + \li \c fileUrl (since Qt 5.15) \li \c fileBaseName \li \c fileSuffix \li \c fileSize @@ -334,7 +335,8 @@ QQuickFolderListModel::QQuickFolderListModel(QObject *parent) d->roleNames[FileLastModifiedRole] = "fileModified"; d->roleNames[FileLastReadRole] = "fileAccessed"; d->roleNames[FileIsDirRole] = "fileIsDir"; - d->roleNames[FileUrlRole] = "fileURL"; + d->roleNames[FileUrlRole] = "fileUrl"; + d->roleNames[FileURLRole] = "fileURL"; d->init(); } @@ -377,6 +379,7 @@ QVariant QQuickFolderListModel::data(const QModelIndex &index, int role) const rv = d->data.at(index.row()).isDir(); break; case FileUrlRole: + case FileURLRole: rv = QUrl::fromLocalFile(d->data.at(index.row()).filePath()); break; default: @@ -886,7 +889,8 @@ void QQuickFolderListModel::setSortCaseSensitive(bool on) \list \li \c fileName \li \c filePath - \li \c fileURL (since Qt 5.2) + \li \c fileURL (since Qt 5.2; deprecated since Qt 5.15) + \li \c fileUrl (since Qt 5.15) \li \c fileBaseName \li \c fileSuffix \li \c fileSize diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h index d7429efeda..e21a8d8f37 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.h +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h @@ -95,7 +95,8 @@ public: FileLastModifiedRole = Qt::UserRole + 6, FileLastReadRole = Qt::UserRole +7, FileIsDirRole = Qt::UserRole + 8, - FileUrlRole = Qt::UserRole + 9 + FileUrlRole = Qt::UserRole + 9, + FileURLRole = Qt::UserRole + 10 }; int rowCount(const QModelIndex &parent = QModelIndex()) const override; diff --git a/src/qml/Qt5QmlConfigExtras.cmake.in b/src/qml/Qt5QmlConfigExtras.cmake.in index 9ddb9885cd..4242143bca 100644 --- a/src/qml/Qt5QmlConfigExtras.cmake.in +++ b/src/qml/Qt5QmlConfigExtras.cmake.in @@ -1,5 +1,7 @@ -file(GLOB _qt5qml_other_plugins "${CMAKE_CURRENT_LIST_DIR}/Qt5Qml_*Factory.cmake") +if(QT5_STRICT_PLUGIN_GLOB OR Qt5Qml_STRICT_PLUGIN_GLOB) + file(GLOB _qt5qml_other_plugins "${CMAKE_CURRENT_LIST_DIR}/Qt5Qml_*Factory.cmake") -foreach(_other_plugin ${_qt5qml_other_plugins}) - include(${_other_plugin} OPTIONAL) -endforeach() + foreach(_other_plugin ${_qt5qml_other_plugins}) + include(${_other_plugin} OPTIONAL) + endforeach() +endif() diff --git a/src/qml/doc/src/external-resources.qdoc b/src/qml/doc/src/external-resources.qdoc index 17ac7693bc..c11174db43 100644 --- a/src/qml/doc/src/external-resources.qdoc +++ b/src/qml/doc/src/external-resources.qdoc @@ -76,3 +76,7 @@ \externalpage https://fontawesome.com/ \title Font Awesome */ +/*! + \externalpage https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator + \title Nullish Coalescing +*/ diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index c22c392b80..bc75f843fb 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -42,6 +42,8 @@ Like a browser or server-side JavaScript environment, the QML runtime implements all of the built-in types and functions defined by the standard, such as Object, Array, and Math. The QML runtime implements the 7th edition of the standard. +Since Qt 5.15 \l{Nullish Coalescing} is also implemented in the QML runtime. + The standard ECMAScript built-ins are not explicitly documented in the QML documentation. For more information on their use, please refer to the ECMA-262 7th edition standard or one of the many online JavaScript reference and tutorial sites, such as the \l{W3Schools JavaScript Reference} (JavaScript Objects diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 55884aa42c..51e63f3608 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1562,7 +1562,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int retn = QVariant(typeHint, temp); QMetaType::destroy(typeHint, temp); auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>(); - if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) { + if (retnAsIterable.containerCapabilities() & QtMetaTypePrivate::ContainerIsAppendable) { auto const length = a->getLength(); QV4::ScopedValue arrayValue(scope); for (qint64 i = 0; i < length; ++i) { diff --git a/src/qml/jsruntime/qv4resolvedtypereference_p.h b/src/qml/jsruntime/qv4resolvedtypereference_p.h index 88b77cf2a8..7e8bedad62 100644 --- a/src/qml/jsruntime/qv4resolvedtypereference_p.h +++ b/src/qml/jsruntime/qv4resolvedtypereference_p.h @@ -67,6 +67,11 @@ class ResolvedTypeReference Q_DISABLE_COPY_MOVE(ResolvedTypeReference) public: ResolvedTypeReference() = default; + ~ResolvedTypeReference() + { + if (m_stronglyReferencesCompilationUnit && m_compilationUnit) + m_compilationUnit->release(); + } QQmlRefPointer<QQmlPropertyCache> propertyCache() const; QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QQmlEngine *); @@ -80,7 +85,33 @@ public: QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() { return m_compilationUnit; } void setCompilationUnit(QQmlRefPointer<QV4::ExecutableCompilationUnit> unit) { - m_compilationUnit = std::move(unit); + if (m_compilationUnit == unit.data()) + return; + if (m_stronglyReferencesCompilationUnit) { + if (m_compilationUnit) + m_compilationUnit->release(); + m_compilationUnit = unit.take(); + } else { + m_compilationUnit = unit.data(); + } + } + + bool referencesCompilationUnit() const { return m_stronglyReferencesCompilationUnit; } + void setReferencesCompilationUnit(bool doReference) + { + if (doReference == m_stronglyReferencesCompilationUnit) + return; + m_stronglyReferencesCompilationUnit = doReference; + if (!m_compilationUnit) + return; + if (doReference) { + m_compilationUnit->addref(); + } else if (m_compilationUnit->count() == 1) { + m_compilationUnit->release(); + m_compilationUnit = nullptr; + } else { + m_compilationUnit->release(); + } } QQmlRefPointer<QQmlPropertyCache> typePropertyCache() const { return m_typePropertyCache; } @@ -98,12 +129,13 @@ public: private: QQmlType m_type; QQmlRefPointer<QQmlPropertyCache> m_typePropertyCache; - QQmlRefPointer<QV4::ExecutableCompilationUnit> m_compilationUnit; + QV4::ExecutableCompilationUnit *m_compilationUnit = nullptr; QTypeRevision m_version = QTypeRevision::zero(); // Types such as QQmlPropertyMap can add properties dynamically at run-time and // therefore cannot have a property cache installed when instantiated. bool m_isFullyDynamicType = false; + bool m_stronglyReferencesCompilationUnit = true; }; } // namespace QV4 diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 6fe8dc5227..a2976b59c3 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -107,8 +107,6 @@ void QQmlApplicationEnginePrivate::_q_loadTranslations() activeTranslator.reset(); } q->retranslate(); -#else - Q_UNUSED(rootFile) #endif } diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h index 70232b3d52..4568f7cfbb 100644 --- a/src/qml/qml/qqmlapplicationengine_p.h +++ b/src/qml/qml/qqmlapplicationengine_p.h @@ -76,8 +76,10 @@ public: QVariantMap initialProperties; QStringList extraFileSelectors; QString translationsDirectory; +#if QT_CONFIG(translation) QScopedPointer<QTranslator> activeTranslator; bool isInitialized = false; +#endif }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index b264528daa..fea0062242 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -300,7 +300,14 @@ void QQmlTypeData::setCompileUnit(const Container &container) auto const root = container->objectAt(i); for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) { auto *typeRef = m_compiledData->resolvedType(it->nameIndex); - typeRef->setCompilationUnit(m_compiledData); // share compilation unit + + // We don't want the type reference to keep a strong reference to the compilation unit + // here. The compilation unit owns the type reference, and having a strong reference + // would prevent the compilation unit from ever getting deleted. We can still be sure + // that the compilation unit outlives the type reference, due to ownership. + typeRef->setReferencesCompilationUnit(false); + + typeRef->setCompilationUnit(m_compiledData); // share compilation unit } } } diff --git a/src/qmldebug/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp index 9d495ce6e4..81b69d1216 100644 --- a/src/qmldebug/qqmldebugconnection.cpp +++ b/src/qmldebug/qqmldebugconnection.cpp @@ -416,8 +416,7 @@ public: { connect(parent, &QLocalSocket::stateChanged, this, &LocalSocketSignalTranslator::onStateChanged); - connect(parent, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>( - &QLocalSocket::errorOccurred), this, &LocalSocketSignalTranslator::onError); + connect(parent, &QLocalSocket::errorOccurred, this, &LocalSocketSignalTranslator::onError); } void onError(QLocalSocket::LocalSocketError error) diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 646ac5e9f9..c94493dee8 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -926,17 +926,11 @@ void PropertyUpdater::doUpdate() auto mo = sender->metaObject(); auto signalIndex = QObject::senderSignalIndex(); ++updateCount; - // start at 0 instead of propertyOffset to handle properties from parent hierarchy - for (auto i = 0; i < mo->propertyCount() + mo->propertyOffset(); ++i) { - auto property = mo->property(i); - if (property.notifySignal().methodIndex() == signalIndex) { - // we synchronize between required properties and model rolenames by name - // that's why the QQmlProperty and the metaobject property must have the same name - QQmlProperty qmlProp(parent(), QString::fromLatin1(property.name())); - qmlProp.write(property.read(QObject::sender())); - return; - } - } + auto property = mo->property(changeSignalIndexToPropertyIndex[signalIndex]); + // we synchronize between required properties and model rolenames by name + // that's why the QQmlProperty and the metaobject property must have the same name + QQmlProperty qmlProp(parent(), QString::fromLatin1(property.name())); + qmlProp.write(property.read(QObject::sender())); } void PropertyUpdater::breakBinding() @@ -1014,8 +1008,10 @@ void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *mod QMetaMethod changeSignal = prop.notifySignal(); static QMetaMethod updateSlot = PropertyUpdater::staticMetaObject.method( PropertyUpdater::staticMetaObject.indexOfSlot("doUpdate()")); + QMetaObject::Connection conn = QObject::connect(itemOrProxy, changeSignal, updater, updateSlot); + updater->changeSignalIndexToPropertyIndex[changeSignal.methodIndex()] = i; auto propIdx = object->metaObject()->indexOfProperty(propName.toUtf8()); QMetaMethod writeToPropSignal = object->metaObject()->property(propIdx).notifySignal(); diff --git a/src/qmlmodels/qqmldelegatemodel_p_p.h b/src/qmlmodels/qqmldelegatemodel_p_p.h index 20fb47f021..491e8025b8 100644 --- a/src/qmlmodels/qqmldelegatemodel_p_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p_p.h @@ -475,6 +475,7 @@ class PropertyUpdater : public QObject public: PropertyUpdater(QObject *parent); QHash<int, QMetaObject::Connection> senderToConnection; + QHash<int, int> changeSignalIndexToPropertyIndex; int updateCount = 0; public Q_SLOTS: void doUpdate(); diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index 4152cbe3ea..332a5447b1 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -232,14 +232,17 @@ QQmlInstanceModel::ReleaseFlags QQmlTableInstanceModel::release(QObject *object, } // The item is not reused or referenced by anyone, so just delete it - destroyModelItem(modelItem); + destroyModelItem(modelItem, Deferred); return QQmlInstanceModel::Destroyed; } -void QQmlTableInstanceModel::destroyModelItem(QQmlDelegateModelItem *modelItem) +void QQmlTableInstanceModel::destroyModelItem(QQmlDelegateModelItem *modelItem, DestructionMode mode) { emit destroyingItem(modelItem->object); - modelItem->destroyObject(); + if (mode == Deferred) + modelItem->destroyObject(); + else + delete modelItem->object; delete modelItem; } @@ -284,7 +287,9 @@ void QQmlTableInstanceModel::cancel(int index) void QQmlTableInstanceModel::drainReusableItemsPool(int maxPoolTime) { - m_reusableItemsPool.drain(maxPoolTime, [=](QQmlDelegateModelItem *modelItem){ destroyModelItem(modelItem); }); + m_reusableItemsPool.drain(maxPoolTime, [this](QQmlDelegateModelItem *modelItem) { + destroyModelItem(modelItem, Immediate); + }); } void QQmlTableInstanceModel::reuseItem(QQmlDelegateModelItem *item, int newModelIndex) diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index 57b9b26e43..defe513ef9 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -124,6 +124,11 @@ public: int indexOf(QObject *, QObject *) const override { Q_UNREACHABLE(); return 0; } private: + enum DestructionMode { + Deferred, + Immediate + }; + QQmlComponent *resolveDelegate(int index); QQmlAdaptorModel m_adaptorModel; @@ -141,7 +146,7 @@ private: void deleteIncubationTaskLater(QQmlIncubator *incubationTask); void deleteAllFinishedIncubationTasks(); QQmlDelegateModelItem *resolveModelItem(int index); - void destroyModelItem(QQmlDelegateModelItem *modelItem); + void destroyModelItem(QQmlDelegateModelItem *modelItem, DestructionMode mode); void dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles); diff --git a/src/qmltest/qmldir b/src/qmltest/qmldir new file mode 100644 index 0000000000..5e9d5e2c95 --- /dev/null +++ b/src/qmltest/qmldir @@ -0,0 +1,2 @@ +module Qt.test.qtestroot +typeinfo plugins.qmltypes diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro index 6864203ba4..c2e8068fc6 100644 --- a/src/qmltest/qmltest.pro +++ b/src/qmltest/qmltest.pro @@ -22,6 +22,7 @@ SOURCES += \ HEADERS += \ $$PWD/quicktestglobal.h \ $$PWD/quicktest.h \ + $$PWD/quicktest_p.h \ $$PWD/quicktestresult_p.h \ $$PWD/qtestoptions_p.h @@ -29,4 +30,15 @@ qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING load(qt_module) -CONFIG += metatypes install_metatypes +QMLTYPES_FILENAME = plugins.qmltypes +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/Qt/test/qtestroot +QML_IMPORT_NAME = Qt.test.qtestroot +QML_IMPORT_VERSION = 1.0 +CONFIG += qmltypes install_qmltypes install_metatypes + +# Install qmldir +qmldir.files = $$PWD/qmldir +qmldir.path = $$QMLTYPES_INSTALL_DIR + +prefix_build: INSTALLS += qmldir +else: COPIES += qmldir diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index b2f54d978f..63e51fa4ba 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "quicktest.h" +#include "quicktest_p.h" #include "quicktestresult_p.h" #include <QtTest/qtestsystem.h> #include "qtestoptions_p.h" @@ -133,53 +133,6 @@ bool QQuickTest::qWaitForItemPolished(const QQuickItem *item, int timeout) return QTest::qWaitFor([&]() { return !QQuickItemPrivate::get(item)->polishScheduled; }, timeout); } -class QTestRootObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged) - Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged) - Q_PROPERTY(QObject *defined READ defined) -public: - QTestRootObject(QObject *parent = nullptr) - : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) { - m_defined = new QQmlPropertyMap(this); -#if defined(QT_OPENGL_ES_2_ANGLE) - m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true)); -#endif - } - - static QTestRootObject *instance() { - static QPointer<QTestRootObject> object = new QTestRootObject; - if (!object) { - // QTestRootObject was deleted when previous test ended, create a new one - object = new QTestRootObject; - } - return object; - } - - bool hasQuit:1; - bool hasTestCase() const { return m_hasTestCase; } - void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); } - - bool windowShown() const { return m_windowShown; } - void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); } - QQmlPropertyMap *defined() const { return m_defined; } - - void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; } - -Q_SIGNALS: - void windowShownChanged(); - void hasTestCaseChanged(); - -private Q_SLOTS: - void quit() { hasQuit = true; } - -private: - bool m_windowShown : 1; - bool m_hasTestCase :1; - QQmlPropertyMap *m_defined; -}; - static QObject *testRootObject(QQmlEngine *engine, QJSEngine *jsEngine) { Q_UNUSED(engine); @@ -556,7 +509,7 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch qputenv("QT_QTESTLIB_RUNNING", "1"); - // Register the test object + // Register the custom factory function qmlRegisterSingletonType<QTestRootObject>("Qt.test.qtestroot", 1, 0, "QTestRootObject", testRootObject); QSet<QString> commandLineTestFunctions(QTest::testFunctions.cbegin(), QTest::testFunctions.cend()); @@ -688,5 +641,3 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch } QT_END_NAMESPACE - -#include "quicktest.moc" diff --git a/src/qmltest/quicktest_p.h b/src/qmltest/quicktest_p.h new file mode 100644 index 0000000000..50fc3be050 --- /dev/null +++ b/src/qmltest/quicktest_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +#ifndef QUICKTEST_P_H +#define QUICKTEST_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTest/quicktest.h> + +#include <QtQml/qqmlpropertymap.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QTestRootObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged) + Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged) + Q_PROPERTY(QObject *defined READ defined) + QML_SINGLETON + QML_ELEMENT + +public: + QTestRootObject(QObject *parent = nullptr) + : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) { + m_defined = new QQmlPropertyMap(this); +#if defined(QT_OPENGL_ES_2_ANGLE) + m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true)); +#endif + } + + static QTestRootObject *instance() { + static QPointer<QTestRootObject> object = new QTestRootObject; + if (!object) { + // QTestRootObject was deleted when previous test ended, create a new one + object = new QTestRootObject; + } + return object; + } + + bool hasQuit:1; + bool hasTestCase() const { return m_hasTestCase; } + void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); } + + bool windowShown() const { return m_windowShown; } + void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); } + QQmlPropertyMap *defined() const { return m_defined; } + + void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; } + +Q_SIGNALS: + void windowShownChanged(); + void hasTestCaseChanged(); + +private Q_SLOTS: + void quit() { hasQuit = true; } + +private: + bool m_windowShown : 1; + bool m_hasTestCase :1; + QQmlPropertyMap *m_defined; +}; + +QT_END_NAMESPACE + +#endif // QUICKTEST_P_H diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 33f1ebbbd5..e6b0ee8cd9 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -331,25 +331,37 @@ int main(int argc, char **argv) } } + const bool privateIncludes = parser.isSet(privateIncludesOption); + auto resolvedInclude = [&](const QString &include) { + return (privateIncludes && include.endsWith(QLatin1String("_p.h"))) + ? QLatin1String("private/") + include + : include; + }; + auto processMetaObject = [&](const QJsonObject &metaObject) { + const QString include = resolvedInclude(metaObject[QLatin1String("inputFile")].toString()); const QJsonArray classes = metaObject[QLatin1String("classes")].toArray(); for (const auto &cls : classes) { QJsonObject classDef = cls.toObject(); + classDef.insert(QLatin1String("inputFile"), include); + switch (qmlTypeRegistrationMode(classDef)) { case NamespaceRegistration: case GadgetRegistration: case ObjectRegistration: { - const QString include = metaObject[QLatin1String("inputFile")].toString(); - const bool declaredInHeader = include.endsWith(QLatin1String(".h")); - if (declaredInHeader) { - includes.append(include); - classDef.insert(QLatin1String("registerable"), true); - } else { - fprintf(stderr, "Cannot generate QML type registration for class %s " - "because it is not declared in a header.", + if (!include.endsWith(QLatin1String(".h")) + && !include.endsWith(QLatin1String(".hpp")) + && !include.endsWith(QLatin1String(".hxx")) + && include.contains(QLatin1Char('.'))) { + fprintf(stderr, + "Class %s is declared in %s, which appears not to be a header.\n" + "The compilation of its registration to QML may fail.\n", qPrintable(classDef.value(QLatin1String("qualifiedClassName")) - .toString())); + .toString()), + qPrintable(include)); } + includes.append(include); + classDef.insert(QLatin1String("registerable"), true); types.append(classDef); break; @@ -395,13 +407,8 @@ int main(int argc, char **argv) const auto newEnd = std::unique(includes.begin(), includes.end()); includes.erase(newEnd, includes.end()); - const bool privateIncludes = parser.isSet(privateIncludesOption); - for (const QString &include : qAsConst(includes)) { - if (privateIncludes && include.endsWith(QLatin1String("_p.h"))) - fprintf(output, "\n#include <private/%s>", qPrintable(include)); - else - fprintf(output, "\n#include <%s>", qPrintable(include)); - } + for (const QString &include : qAsConst(includes)) + fprintf(output, "\n#include <%s>", qPrintable(include)); fprintf(output, "\n\n"); @@ -463,9 +470,13 @@ int main(int argc, char **argv) continue; } + const QString include = metaObject[QLatin1String("inputFile")].toString(); const QJsonArray classes = metaObject[QLatin1String("classes")].toArray(); - for (const auto &cls : classes) - foreignTypes.append(cls.toObject()); + for (const auto &cls : classes) { + QJsonObject classDef = cls.toObject(); + classDef.insert(QLatin1String("inputFile"), include); + foreignTypes.append(classDef); + } } } } diff --git a/src/qmltyperegistrar/qmltypes.prf b/src/qmltyperegistrar/qmltypes.prf index fbb00dbe2d..0d5a6ded24 100644 --- a/src/qmltyperegistrar/qmltypes.prf +++ b/src/qmltyperegistrar/qmltypes.prf @@ -31,7 +31,7 @@ isEmpty(QML_IMPORT_MINOR_VERSION) { isEmpty(QMLTYPES_FILENAME) { plugin: QMLTYPES_FILENAME = plugins.qmltypes - else: QMLTYPES_FILENAME = $${TEMPLATE}.qmltypes + else: QMLTYPES_FILENAME = $${TARGET}.qmltypes } qt_module_deps = $$replace(QT, -private$, '') @@ -40,25 +40,25 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depen qt_module_deps = $$replace(qt_module_deps, _private$, '') qt_module_deps = $$unique(qt_module_deps) -foreign_types = for(dep, qt_module_deps) { METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))_metatypes.json INSTALLED_METATYPES = $$[QT_INSTALL_LIBS]/metatypes/$$METATYPES_FILENAME isEmpty(MODULE_BASE_OUTDIR) { - foreign_types += $$INSTALLED_METATYPES + QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES } else { MODULE_BASE_METATYPES = $$MODULE_BASE_OUTDIR/lib/metatypes/$$METATYPES_FILENAME - exists($$MODULE_BASE_METATYPES): foreign_types += $$MODULE_BASE_METATYPES - else: foreign_types += $$INSTALLED_METATYPES + exists($$MODULE_BASE_METATYPES): QML_FOREIGN_METATYPES += $$MODULE_BASE_METATYPES + else: QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES } } + QML_TYPEREGISTRAR_FLAGS = \ --generate-qmltypes=$$QMLTYPES_FILENAME \ --import-name=$$QML_IMPORT_NAME \ --major-version=$$QML_IMPORT_MAJOR_VERSION \ --minor-version=$$QML_IMPORT_MINOR_VERSION \ - --foreign-types=$$join(foreign_types, ',') + --foreign-types=$$join(QML_FOREIGN_METATYPES, ',') DEPENDENCIESFILE = $$_PRO_FILE_PWD_/dependencies.json exists($$DEPENDENCIESFILE): QML_TYPEREGISTRAR_FLAGS += --dependencies=$$DEPENDENCIESFILE diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index e21abd97bc..778d057240 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -63,6 +63,8 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QVector<QJsonObject> &foreign, CollectMode mode, QTypeRevision defaultRevision) { + if (file.isEmpty() && classDef->value(QLatin1String("registerable")).toBool()) + file = classDef->value(QLatin1String("inputFile")).toString(); const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); for (const QJsonValue &classInfo : classInfos) { const QJsonObject obj = classInfo.toObject(); diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index e4ae37a84e..abe68d42ed 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -38,6 +38,7 @@ struct QmlTypesClassDescription { const QJsonObject *resolvedClass = nullptr; + QString file; QString elementName; QString defaultProp; QString superClass; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 3569bbe253..d1378d809d 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -46,6 +46,8 @@ static QString enquote(const QString &string) void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &collector) { + if (!collector.file.isEmpty()) + m_qml.writeScriptBinding(QLatin1String("file"), enquote(collector.file)); m_qml.writeScriptBinding( QLatin1String("name"), enquote(collector.resolvedClass->value( diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 8361be7277..12a4ce32df 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -986,10 +986,11 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE pixelData->setPrototypeOf(p); if (image.isNull()) { - *pixelData->d()->image = QImage(w, h, QImage::Format_ARGB32); + *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32); pixelData->d()->image->fill(0x00000000); } else { - Q_ASSERT(image.width()== qRound(w * image.devicePixelRatioF()) && image.height() == qRound(h * image.devicePixelRatioF())); + // After qtbase 88e56d0932a3615231adf40d5ae033e742d72c33, the image size can be off by one. + Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatioF())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatioF())) <= 1); *pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32); } diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 9469a9a06c..22b8877b9f 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -2171,7 +2171,7 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i tpCopy.setPos(item->mapFromScene(tpCopy.scenePos())); tpCopy.setLastPos(item->mapFromScene(tpCopy.lastScenePos())); tpCopy.setStartPos(item->mapFromScene(tpCopy.startScenePos())); - tpCopy.setRect(item->mapRectFromScene(tpCopy.sceneRect())); + tpCopy.setEllipseDiameters(tpCopy.ellipseDiameters()); tpCopy.setVelocity(transformMatrix.mapVector(tpCopy.velocity()).toVector2D()); touchPoints << tpCopy; } diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index c7f641cf1f..c91a5ef92b 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1897,6 +1897,9 @@ void QQuickFlickable::cancelFlick() void QQuickFlickablePrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o) { + if (!prop || !prop->data) + return; + if (QQuickItem *i = qmlobject_cast<QQuickItem *>(o)) { i->setParentItem(static_cast<QQuickFlickablePrivate*>(prop->data)->contentItem); } else if (QQuickPointerHandler *pointerHandler = qmlobject_cast<QQuickPointerHandler *>(o)) { diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index a1f8fd35d8..cb1d3e224e 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -3977,6 +3977,9 @@ void QQuickItem::focusOutEvent(QFocusEvent * /*event*/) press events for an item. The event information is provided by the \a event parameter. + In order to receive mouse press events, \l acceptedMouseButtons() must + return the relevant mouse button. + \input item.qdocinc accepting-events */ void QQuickItem::mousePressEvent(QMouseEvent *event) @@ -3989,6 +3992,10 @@ void QQuickItem::mousePressEvent(QMouseEvent *event) move events for an item. The event information is provided by the \a event parameter. + In order to receive mouse movement events, the preceding mouse press event + must be accepted (by overriding \l mousePressEvent(), for example) and + \l acceptedMouseButtons() must return the relevant mouse button. + \input item.qdocinc accepting-events */ void QQuickItem::mouseMoveEvent(QMouseEvent *event) @@ -4001,6 +4008,10 @@ void QQuickItem::mouseMoveEvent(QMouseEvent *event) release events for an item. The event information is provided by the \a event parameter. + In order to receive mouse release events, the preceding mouse press event + must be accepted (by overriding \l mousePressEvent(), for example) and + \l acceptedMouseButtons() must return the relevant mouse button. + \input item.qdocinc accepting-events */ void QQuickItem::mouseReleaseEvent(QMouseEvent *event) diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index fd2458494c..f54858e4eb 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -1063,6 +1063,12 @@ void QQuickMouseArea::itemChange(ItemChange change, const ItemChangeData &value) } setHovered(!d->hovered); } + if (d->pressed && (!isVisible())) { + // This happens when the mouse area sets itself disabled or hidden + // inside the press handler. In that case we should not keep the internal + // state as pressed, since we never became the mouse grabber. + ungrabMouse(); + } break; default: break; diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index a854d97f7e..383718c979 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -789,7 +789,9 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QT dtp->setPressure(p->pressure()); dtp->setRotation(p->rotation()); dtp->setVelocity(p->velocity()); - dtp->setArea(p->rect()); + QRectF area(QPointF(), p->ellipseDiameters()); + area.moveCenter(p->pos()); + dtp->setArea(area); dtp->setStartX(p->startPos().x()); dtp->setStartY(p->startPos().y()); dtp->setPreviousX(p->lastPos().x()); diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index f963bdf74f..0692a1da42 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -194,7 +194,7 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() */ /*! - \qmlsignal QtQuick::PinchArea::pinchStarted() + \qmlsignal QtQuick::PinchArea::pinchStarted(PinchEvent pinch) This signal is emitted when the pinch area detects that a pinch gesture has started: two touch points (fingers) have been detected, and they have moved @@ -213,7 +213,7 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() */ /*! - \qmlsignal QtQuick::PinchArea::pinchUpdated() + \qmlsignal QtQuick::PinchArea::pinchUpdated(PinchEvent pinch) This signal is emitted when the pinch area detects that a pinch gesture has changed. @@ -225,7 +225,7 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() */ /*! - \qmlsignal QtQuick::PinchArea::pinchFinished() + \qmlsignal QtQuick::PinchArea::pinchFinished(PinchEvent pinch) This signal is emitted when the pinch area detects that a pinch gesture has finished. @@ -235,7 +235,7 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() */ /*! - \qmlsignal QtQuick::PinchArea::smartZoom() + \qmlsignal QtQuick::PinchArea::smartZoom(PinchEvent pinch) \since 5.5 This signal is emitted when the pinch area detects the smart zoom gesture. diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index dc1c820309..eade79e683 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -78,9 +78,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged) Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged) Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged) - // TODO Qt 6 Rename primaryOrientation to orientation Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged) - // TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged) Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION(2, 3)) diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 3548d20706..5adfd20bf0 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ @@ -193,8 +193,10 @@ \qmlproperty int QtQuick::TableView::rows \readonly - This property holds the number of rows in the table. This is - equal to the number of rows in the model. + This property holds the number of rows in the table. + + \note \a rows is usually equal to the number of rows in the model, but can + temporarily differ until all pending model changes have been processed. This property is read only. */ @@ -203,9 +205,12 @@ \qmlproperty int QtQuick::TableView::columns \readonly - This property holds the number of columns in the table. This is - equal to the number of columns in the model. If the model is - a list, columns will be \c 1. + This property holds the number of rows in the table. + + \note \a columns is usually equal to the number of columns in the model, but + can temporarily differ until all pending model changes have been processed. + + If the model is a list, columns will be \c 1. This property is read only. */ @@ -549,6 +554,8 @@ QQuickTableViewPrivate::~QQuickTableViewPrivate() QString QQuickTableViewPrivate::tableLayoutToString() const { + if (loadedItems.isEmpty()) + return QLatin1String("table is empty!"); return QString(QLatin1String("table cells: (%1,%2) -> (%3,%4), item count: %5, table rect: %6,%7 x %8,%9")) .arg(leftColumn()).arg(topRow()) .arg(rightColumn()).arg(bottomRow()) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index acf6fd68c8..4874af44ed 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -976,8 +976,7 @@ void QQuickWindowPrivate::translateTouchEvent(QTouchEvent *touchEvent) QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints(); for (int i = 0; i < touchPoints.count(); ++i) { QTouchEvent::TouchPoint &touchPoint = touchPoints[i]; - - touchPoint.setSceneRect(touchPoint.rect()); + touchPoint.setScenePos(touchPoint.pos()); touchPoint.setStartScenePos(touchPoint.startPos()); touchPoint.setLastScenePos(touchPoint.lastPos()); } diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 14314b2c94..ed2f8c313f 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -242,8 +242,6 @@ void QSGDefaultRenderContext::beginNextRhiFrame(QSGRenderer *renderer, QRhiRende RenderPassCallback mainPassRecordingEnd, void *callbackUserData) { - Q_ASSERT(!m_currentFrameCommandBuffer); - renderer->setRenderTarget(rt); renderer->setRenderPassDescriptor(rp); renderer->setCommandBuffer(cb); diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 90c725a67f..e5e25d141b 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -176,11 +176,8 @@ void QQuickAbstractAnimationPrivate::commence() animationInstance = new QQuickAnimatorProxyJob(animationInstance, q); animationInstance->addAnimationChangeListener(this, QAbstractAnimationJob::Completion); } + emit q->started(); animationInstance->start(); - if (animationInstance->isStopped()) { - running = false; - emit q->stopped(); - } } } @@ -287,10 +284,8 @@ void QQuickAbstractAnimation::setRunning(bool r) d->animationInstance->setLoopCount(d->animationInstance->currentLoop() + d->loopCount); supressStart = true; //we want the animation to continue, rather than restart } - if (!supressStart) { + if (!supressStart) d->commence(); - emit started(); - } } else { if (d->paused) { d->paused = false; //reset paused state to false when stopped @@ -308,7 +303,16 @@ void QQuickAbstractAnimation::setRunning(bool r) } } - emit runningChanged(d->running); + + if (r == d->running) { + // This might happen if we start an animation with 0 duration: This will result in that + // commence() will emit started(), and then when it starts it will call setCurrentTime(0), + // (which is both start and end time of the animation), so it will also end up calling + // setRunning(false) (recursively) and stop the animation. + // Therefore, the state of d->running will in that case be different than r if we are back in + // the root stack frame of the recursive calls to setRunning() + emit runningChanged(d->running); + } } /*! diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index db7ae22767..59d4a89fbf 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -109,6 +109,7 @@ void QQuickWidgetPrivate::init(QQmlEngine* e) renderControl = new QQuickWidgetRenderControl(q); offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl); offscreenWindow->setTitle(QString::fromLatin1("Offscreen")); + offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow")); // Do not call create() on offscreenWindow. // Check if the Software Adaptation is being used @@ -804,15 +805,29 @@ void QQuickWidgetPrivate::updateSize() q->updateGeometry(); } } else if (resizeMode == QQuickWidget::SizeRootObjectToView) { - bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width()); - bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height()); - - if (needToUpdateWidth && needToUpdateHeight) - root->setSize(QSizeF(q->width(), q->height())); - else if (needToUpdateWidth) - root->setWidth(q->width()); - else if (needToUpdateHeight) - root->setHeight(q->height()); + const bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width()); + const bool needToUpdateHeight = !qFuzzyCompare(q->height(), root->height()); + + if (needToUpdateWidth && needToUpdateHeight) { + // Make sure that we have realistic sizing behavior by following + // what on-screen windows would do and resize everything, not just + // the root item. We do this because other types may be relying on + // us to behave correctly. + const QSizeF newSize(q->width(), q->height()); + offscreenWindow->resize(newSize.toSize()); + offscreenWindow->contentItem()->setSize(newSize); + root->setSize(newSize); + } else if (needToUpdateWidth) { + const int newWidth = q->width(); + offscreenWindow->setWidth(newWidth); + offscreenWindow->contentItem()->setWidth(newWidth); + root->setWidth(newWidth); + } else if (needToUpdateHeight) { + const int newHeight = q->height(); + offscreenWindow->setHeight(newHeight); + offscreenWindow->contentItem()->setHeight(newHeight); + root->setHeight(newHeight); + } } } |