diff options
Diffstat (limited to 'src/quicktemplates2')
40 files changed, 877 insertions, 96 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index cc918c0c..a7fe720a 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -40,6 +40,7 @@ #include "qquickaction_p.h" #include "qquickaction_p_p.h" #include "qquickshortcutcontext_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtGui/qstylehints.h> #include <QtGui/qguiapplication.h> @@ -308,6 +309,20 @@ void QQuickAbstractButtonPrivate::toggle(bool value) emit q->toggled(); } +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickAbstractButtonPrivate::executeIndicator(bool complete) +{ + Q_Q(QQuickControl); + if (indicator.wasExecuted()) + return; + + if (!indicator) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} + QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const { Q_Q(const QQuickAbstractButton); @@ -604,7 +619,9 @@ void QQuickAbstractButton::setAutoRepeat(bool repeat) */ QQuickItem *QQuickAbstractButton::indicator() const { - Q_D(const QQuickAbstractButton); + QQuickAbstractButtonPrivate *d = const_cast<QQuickAbstractButtonPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -614,14 +631,15 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; - QQuickControlPrivate::destroyDelegate(d->indicator, this); + delete d->indicator; d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) indicator->setParentItem(this); indicator->setAcceptedMouseButtons(Qt::LeftButton); } - emit indicatorChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); } /*! @@ -791,6 +809,13 @@ void QQuickAbstractButton::toggle() setChecked(!d->checked); } +void QQuickAbstractButton::componentComplete() +{ + Q_D(QQuickAbstractButton); + d->executeIndicator(true); + QQuickControl::componentComplete(); +} + bool QQuickAbstractButton::event(QEvent *event) { Q_D(QQuickAbstractButton); diff --git a/src/quicktemplates2/qquickabstractbutton_p.h b/src/quicktemplates2/qquickabstractbutton_p.h index ecce4299..cc3cce91 100644 --- a/src/quicktemplates2/qquickabstractbutton_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p.h @@ -70,6 +70,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAbstractButton : public QQuickContr Q_PROPERTY(QQuickIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL REVISION 3) Q_PROPERTY(Display display READ display WRITE setDisplay NOTIFY displayChanged FINAL REVISION 3) Q_PROPERTY(QQuickAction *action READ action WRITE setAction NOTIFY actionChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator") public: explicit QQuickAbstractButton(QQuickItem *parent = nullptr); @@ -150,6 +151,8 @@ Q_SIGNALS: protected: QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent); + void componentComplete() override; + bool event(QEvent *event) override; void focusOutEvent(QFocusEvent *event) override; void keyPressEvent(QKeyEvent *event) override; diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index 659846e5..2436d242 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -94,6 +94,8 @@ public: void trigger(); void toggle(bool value); + void executeIndicator(bool complete = false); + QString text; bool down; bool explicitDown; @@ -114,7 +116,7 @@ public: QQuickIcon icon; QPointF pressPoint; Qt::MouseButtons pressButtons; - QQuickItem *indicator; + QQuickDeferredPointer<QQuickItem> indicator; QQuickButtonGroup *group; QQuickAbstractButton::Display display; QPointer<QQuickAction> action; diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index d579afb2..94b0de98 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -43,6 +43,8 @@ #include "qquicktoolbar_p.h" #include "qquicktabbar_p.h" #include "qquickdialogbuttonbox_p.h" +#include "qquickdeferredexecute_p_p.h" +#include "qquickdeferredpointer_p_p.h" #include <QtCore/private/qobject_p.h> #include <QtQuick/private/qquickitem_p.h> @@ -164,8 +166,10 @@ public: static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + void executeBackground(bool complete = false); + bool complete; - QQuickItem *background; + QQuickDeferredPointer<QQuickItem> background; QQuickItem *contentItem; QQuickItem *menuBar; QQuickItem *header; @@ -328,6 +332,20 @@ void QQuickApplicationWindowPrivate::contentData_append(QQmlListProperty<QObject QQuickPopupPrivate::get(popup)->setWindow(static_cast<QQuickApplicationWindow *>(prop->data)); } +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickApplicationWindowPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickApplicationWindow); + if (background.wasExecuted()) + return; + + if (!background) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + QQuickApplicationWindow::QQuickApplicationWindow(QWindow *parent) : QQuickWindowQmlImpl(parent), d_ptr(new QQuickApplicationWindowPrivate) { @@ -374,7 +392,9 @@ QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties( */ QQuickItem *QQuickApplicationWindow::background() const { - Q_D(const QQuickApplicationWindow); + QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -384,7 +404,7 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background) if (d->background == background) return; - QQuickControlPrivate::destroyDelegate(d->background, this); + delete d->background; d->background = background; if (background) { background->setParentItem(QQuickWindow::contentItem()); @@ -393,7 +413,8 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background) if (isComponentComplete()) d->relayout(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -812,6 +833,7 @@ void QQuickApplicationWindow::componentComplete() { Q_D(QQuickApplicationWindow); d->complete = true; + d->executeBackground(true); QQuickWindowQmlImpl::componentComplete(); d->relayout(); } diff --git a/src/quicktemplates2/qquickapplicationwindow_p.h b/src/quicktemplates2/qquickapplicationwindow_p.h index 4e24009f..d74d3c9d 100644 --- a/src/quicktemplates2/qquickapplicationwindow_p.h +++ b/src/quicktemplates2/qquickapplicationwindow_p.h @@ -76,6 +76,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindow : public QQuickWi // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) Q_PROPERTY(QQuickItem *menuBar READ menuBar WRITE setMenuBar NOTIFY menuBarChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background") Q_CLASSINFO("DefaultProperty", "contentData") public: diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 6b20e6a5..3b37900d 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -39,6 +39,7 @@ #include "qquickabstractbutton_p.h" #include "qquickabstractbutton_p_p.h" #include "qquickpopup_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtCore/qregexp.h> #include <QtCore/qabstractitemmodel.h> @@ -255,6 +256,9 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void executeIndicator(bool complete = false); + void executePopup(bool complete = false); + bool flat; bool down; bool hasDown; @@ -272,8 +276,8 @@ public: QQuickItem *pressedItem; QQmlInstanceModel *delegateModel; QQmlComponent *delegate; - QQuickItem *indicator; - QQuickPopup *popup; + QQuickDeferredPointer<QQuickItem> indicator; + QQuickDeferredPointer<QQuickPopup> popup; struct ExtraData { ExtraData() @@ -318,6 +322,9 @@ bool QQuickComboBoxPrivate::isPopupVisible() const void QQuickComboBoxPrivate::showPopup() { + if (!popup) + executePopup(true); + if (popup && !popup->isVisible()) popup->open(); } @@ -335,13 +342,10 @@ void QQuickComboBoxPrivate::hidePopup(bool accept) void QQuickComboBoxPrivate::togglePopup(bool accept) { - if (!popup) - return; - - if (popup->isVisible()) - hidePopup(accept); - else + if (!popup || !popup->isVisible()) showPopup(); + else + hidePopup(accept); } void QQuickComboBoxPrivate::popupVisibleChanged() @@ -398,8 +402,11 @@ void QQuickComboBoxPrivate::createdItem(int index, QObject *object) { Q_Q(QQuickComboBox); QQuickItem *item = qobject_cast<QQuickItem *>(object); - if (popup && item && !item->parentItem()) { - item->setParentItem(popup->contentItem()); + if (item && !item->parentItem()) { + if (popup) + item->setParentItem(popup->contentItem()); + else + item->setParentItem(q); QQuickItemPrivate::get(item)->setCulled(true); } @@ -695,6 +702,34 @@ void QQuickComboBoxPrivate::handleUngrab() q->setPressed(false); } +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickComboBoxPrivate::executeIndicator(bool complete) +{ + Q_Q(QQuickComboBox); + if (indicator.wasExecuted()) + return; + + if (!indicator) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} + +static inline QString popupName() { return QStringLiteral("popup"); } + +void QQuickComboBoxPrivate::executePopup(bool complete) +{ + Q_Q(QQuickComboBox); + if (popup.wasExecuted()) + return; + + if (!popup) + quickBeginDeferred(q, popupName(), popup); + if (complete) + quickCompleteDeferred(q, popupName(), popup); +} + QQuickComboBox::QQuickComboBox(QQuickItem *parent) : QQuickControl(*(new QQuickComboBoxPrivate), parent) { @@ -710,14 +745,13 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent) QQuickComboBox::~QQuickComboBox() { Q_D(QQuickComboBox); - // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal - // emission during the destruction of the (visible) popup. (QTBUG-57650) - QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); - - // Delete the popup directly instead of calling setPopup(nullptr) to avoid calling - // destroyDelegate(popup) and potentially accessing a destroyed QML context. (QTBUG-50992) - delete d->popup; - d->popup = nullptr; + if (d->popup) { + // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal + // emission during the destruction of the (visible) popup. (QTBUG-57650) + QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + delete d->popup; + d->popup = nullptr; + } } /*! @@ -1002,7 +1036,9 @@ void QQuickComboBox::setDelegate(QQmlComponent* delegate) */ QQuickItem *QQuickComboBox::indicator() const { - Q_D(const QQuickComboBox); + QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -1012,13 +1048,14 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; - QQuickControlPrivate::destroyDelegate(d->indicator, this); + delete d->indicator; d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) indicator->setParentItem(this); } - emit indicatorChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); } /*! @@ -1036,7 +1073,9 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) */ QQuickPopup *QQuickComboBox::popup() const { - Q_D(const QQuickComboBox); + QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func()); + if (!d->popup) + d->executePopup(isComponentComplete()); return d->popup; } @@ -1047,8 +1086,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) return; if (d->popup) { - QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); - QQuickControlPrivate::destroyDelegate(d->popup, this); + QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + delete d->popup; } if (popup) { QQuickPopupPrivate::get(popup)->allowVerticalFlip = true; @@ -1059,7 +1098,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange); } d->popup = popup; - emit popupChanged(); + if (!d->popup.isExecuting()) + emit popupChanged(); } /*! @@ -1537,9 +1577,8 @@ void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) { Q_D(QQuickComboBox); QQuickControl::keyReleaseEvent(event); - d->keyNavigating = false; - if (!d->popup || event->isAutoRepeat()) + if (event->isAutoRepeat()) return; switch (event->key()) { @@ -1586,6 +1625,9 @@ void QQuickComboBox::wheelEvent(QWheelEvent *event) void QQuickComboBox::componentComplete() { Q_D(QQuickComboBox); + d->executeIndicator(true); + if (d->popup) + d->executePopup(true); QQuickControl::componentComplete(); if (d->delegateModel && d->ownModel) diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index dd1e1d4f..ee926daf 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -82,6 +82,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged FINAL REVISION 2) Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged FINAL REVISION 2) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged FINAL REVISION 2) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator,popup") public: explicit QQuickComboBox(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp index 07fe04d2..048cfdfa 100644 --- a/src/quicktemplates2/qquickcontainer.cpp +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -634,6 +634,9 @@ QVariant QQuickContainer::contentModel() const */ QQmlListProperty<QObject> QQuickContainer::contentData() { + Q_D(QQuickContainer); + if (!d->contentItem) + d->executeContentItem(); return QQmlListProperty<QObject>(this, nullptr, QQuickContainerPrivate::contentData_append, QQuickContainerPrivate::contentData_count, diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 1db8932b..76d6a688 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -48,6 +48,7 @@ #include "qquickpopup_p.h" #include "qquickpopupitem_p_p.h" #include "qquickapplicationwindow_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformtheme.h> @@ -279,6 +280,8 @@ void QQuickControlPrivate::resizeContent() QQuickItem *QQuickControlPrivate::getContentItem() { + if (!contentItem) + executeContentItem(); return contentItem; } @@ -289,7 +292,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) return; q->contentItemChange(item, contentItem); - destroyDelegate(contentItem, q); + delete contentItem; contentItem = item; if (item) { @@ -299,7 +302,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) resizeContent(); } - if (notify) + if (notify && !contentItem.isExecuting()) emit q->contentItemChanged(); } @@ -644,6 +647,34 @@ bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item) } #endif +static inline QString contentItemName() { return QStringLiteral("contentItem"); } + +void QQuickControlPrivate::executeContentItem(bool complete) +{ + Q_Q(QQuickControl); + if (contentItem.wasExecuted()) + return; + + if (!contentItem) + quickBeginDeferred(q, contentItemName(), contentItem); + if (complete) + quickCompleteDeferred(q, contentItemName(), contentItem); +} + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickControlPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickControl); + if (background.wasExecuted()) + return; + + if (!background) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + /* Cancels incubation recursively to avoid "Object destroyed during incubation" (QTBUG-50992) */ @@ -1270,7 +1301,9 @@ void QQuickControl::setWheelEnabled(bool enabled) */ QQuickItem *QQuickControl::background() const { - Q_D(const QQuickControl); + QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -1280,7 +1313,7 @@ void QQuickControl::setBackground(QQuickItem *background) if (d->background == background) return; - QQuickControlPrivate::destroyDelegate(d->background, this); + delete d->background; d->background = background; if (background) { background->setParentItem(this); @@ -1289,7 +1322,8 @@ void QQuickControl::setBackground(QQuickItem *background) if (isComponentComplete()) d->resizeBackground(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -1414,6 +1448,8 @@ void QQuickControl::classBegin() void QQuickControl::componentComplete() { Q_D(QQuickControl); + d->executeBackground(true); + d->executeContentItem(true); QQuickItem::componentComplete(); d->resizeContent(); if (!d->hasLocale) diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 7dd1deb3..6b2d48d6 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -81,6 +81,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") public: explicit QQuickControl(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index e7e9d46f..f159c96d 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -49,6 +49,7 @@ // #include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQml/private/qlazilyallocated_p.h> @@ -139,6 +140,9 @@ public: static bool calcHoverEnabled(const QQuickItem *item); #endif + void executeContentItem(bool complete = false); + void executeBackground(bool complete = false); + static void destroyDelegate(QObject *object, QObject *parent); struct ExtraData { @@ -170,8 +174,8 @@ public: QPalette resolvedPalette; Qt::FocusPolicy focusPolicy; Qt::FocusReason focusReason; - QQuickItem *background; - QQuickItem *contentItem; + QQuickDeferredPointer<QQuickItem> background; + QQuickDeferredPointer<QQuickItem> contentItem; }; QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp new file mode 100644 index 00000000..802ed3d0 --- /dev/null +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 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 "qquickdeferredexecute_p_p.h" + +#include <QtCore/qhash.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/private/qqmldata_p.h> +#include <QtQml/private/qqmlcomponent_p.h> +#include <QtQml/private/qqmlobjectcreator_p.h> + +QT_BEGIN_NAMESPACE + +namespace QtQuickPrivate { + +typedef QHash<uint, QQmlComponentPrivate::DeferredState *> DeferredStates; + +static inline uint qHash(QObject *object, const QString &propertyName) +{ + return ::qHash(object) + ::qHash(propertyName); +} + +Q_GLOBAL_STATIC(DeferredStates, deferredStates) + +static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState) +{ + QObject *object = property.object(); + QQmlData *ddata = QQmlData::get(object); + Q_ASSERT(!ddata->deferredData.isEmpty()); + + int propertyIndex = property.index(); + + for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) { + QQmlData::DeferredData *deferData = *dit; + + auto range = deferData->bindings.equal_range(propertyIndex); + if (range.first == deferData->bindings.end()) + continue; + + QQmlComponentPrivate::ConstructionState *state = new QQmlComponentPrivate::ConstructionState; + state->completePending = true; + + QQmlContextData *creationContext = nullptr; + state->creator.reset(new QQmlObjectCreator(deferData->context->parent, deferData->compilationUnit, creationContext)); + + enginePriv->inProgressCreations++; + + typedef QMultiHash<int, const QV4::CompiledData::Binding *> QV4PropertyBindingHash; + auto it = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.second); + auto last = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.first); + while (it != last) { + if (!state->creator->populateDeferredBinding(property, deferData, *it)) + state->errors << state->creator->errors; + ++it; + } + + deferredState->constructionStates += state; + + // Cleanup any remaining deferred bindings for this property, also in inner contexts, + // to avoid executing them later and overriding the property that was just populated. + while (dit != ddata->deferredData.rend()) { + (*dit)->bindings.remove(propertyIndex); + ++dit; + } + break; + } +} + +void beginDeferred(QObject *object, const QString &property) +{ + QQmlData *data = QQmlData::get(object); + if (data && !data->deferredData.isEmpty() && !data->wasDeleted(object)) { + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine); + + QQmlComponentPrivate::DeferredState *state = new QQmlComponentPrivate::DeferredState; + beginDeferred(ep, QQmlProperty(object, property), state); + + // Release deferred data for those compilation units that no longer have deferred bindings + data->releaseDeferredData(); + + deferredStates()->insert(qHash(object, property), state); + } +} + +void completeDeferred(QObject *object, const QString &property) +{ + QQmlData *data = QQmlData::get(object); + QQmlComponentPrivate::DeferredState *state = deferredStates()->take(qHash(object, property)); + if (data && state && !data->wasDeleted(object)) { + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine); + QQmlComponentPrivate::completeDeferred(ep, state); + } + delete state; +} + +} // QtQuickPrivate + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickdeferredexecute_p_p.h b/src/quicktemplates2/qquickdeferredexecute_p_p.h new file mode 100644 index 00000000..87124e48 --- /dev/null +++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 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 QQUICKDEFERREDEXECUTE_P_P_H +#define QQUICKDEFERREDEXECUTE_P_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 <QtCore/qglobal.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> + +QT_BEGIN_NAMESPACE + +class QString; +class QObject; + +namespace QtQuickPrivate { + void beginDeferred(QObject *object, const QString &property); + void completeDeferred(QObject *object, const QString &property); +} + +template<typename T> +void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate) +{ + Q_ASSERT(delegate.isNull()); + delegate.setExecuting(true); + QtQuickPrivate::beginDeferred(object, property); + delegate.setExecuting(false); +} + +template<typename T> +void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate) +{ + Q_ASSERT(!delegate.wasExecuted()); + delegate.setExecuting(true); + QtQuickPrivate::completeDeferred(object, property); + delegate.setExecuting(false); + delegate.setExecuted(); +} + +QT_END_NAMESPACE + +#endif // QQUICKDEFERREDEXECUTE_P_P_H diff --git a/src/quicktemplates2/qquickdeferredpointer_p_p.h b/src/quicktemplates2/qquickdeferredpointer_p_p.h new file mode 100644 index 00000000..c793964f --- /dev/null +++ b/src/quicktemplates2/qquickdeferredpointer_p_p.h @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 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 QQUICKDEFERREDPOINTER_P_P_H +#define QQUICKDEFERREDPOINTER_P_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 <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +template<typename T> +class QQuickDeferredPointer +{ +public: + inline QQuickDeferredPointer(); + inline QQuickDeferredPointer(T *); + inline QQuickDeferredPointer(const QQuickDeferredPointer<T> &o); + + inline bool isNull() const; + + inline bool wasExecuted() const; + inline void setExecuted(); + + inline bool isExecuting() const; + inline void setExecuting(bool); + + inline operator T*() const; + inline operator bool() const; + + inline T *data() const; + inline T *operator*() const; + inline T *operator->() const; + + inline QQuickDeferredPointer<T> &operator=(T *); + inline QQuickDeferredPointer<T> &operator=(const QQuickDeferredPointer &o); + +private: + quintptr ptr_value; + + static const quintptr WasExecutedBit = 0x1; + static const quintptr IsExecutingBit = 0x2; + static const quintptr FlagsMask = WasExecutedBit | IsExecutingBit; +}; + +template<typename T> +QQuickDeferredPointer<T>::QQuickDeferredPointer() +: ptr_value(0) +{ +} + +template<typename T> +QQuickDeferredPointer<T>::QQuickDeferredPointer(T *v) +: ptr_value(quintptr(v)) +{ + Q_ASSERT((ptr_value & FlagsMask) == 0); +} + +template<typename T> +QQuickDeferredPointer<T>::QQuickDeferredPointer(const QQuickDeferredPointer<T> &o) +: ptr_value(o.ptr_value) +{ +} + +template<typename T> +bool QQuickDeferredPointer<T>::isNull() const +{ + return 0 == (ptr_value & (~FlagsMask)); +} + +template<typename T> +bool QQuickDeferredPointer<T>::wasExecuted() const +{ + return ptr_value & WasExecutedBit; +} + +template<typename T> +void QQuickDeferredPointer<T>::setExecuted() +{ + ptr_value |= WasExecutedBit; +} + +template<typename T> +bool QQuickDeferredPointer<T>::isExecuting() const +{ + return ptr_value & IsExecutingBit; +} + +template<typename T> +void QQuickDeferredPointer<T>::setExecuting(bool b) +{ + if (b) + ptr_value |= IsExecutingBit; + else + ptr_value &= ~IsExecutingBit; +} + +template<typename T> +QQuickDeferredPointer<T>::operator T*() const +{ + return data(); +} + +template<typename T> +QQuickDeferredPointer<T>::operator bool() const +{ + return !isNull(); +} + +template<typename T> +T *QQuickDeferredPointer<T>::data() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template<typename T> +T *QQuickDeferredPointer<T>::operator*() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template<typename T> +T *QQuickDeferredPointer<T>::operator->() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template<typename T> +QQuickDeferredPointer<T> &QQuickDeferredPointer<T>::operator=(T *o) +{ + Q_ASSERT((quintptr(o) & FlagsMask) == 0); + + ptr_value = quintptr(o) | (ptr_value & FlagsMask); + return *this; +} + +template<typename T> +QQuickDeferredPointer<T> &QQuickDeferredPointer<T>::operator=(const QQuickDeferredPointer &o) +{ + ptr_value = o.ptr_value; + return *this; +} + +QT_END_NAMESPACE + +#endif // QQUICKDEFERREDPOINTER_P_P_H diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index c0e2c8ed..964cefe1 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -35,6 +35,7 @@ ****************************************************************************/ #include "qquickdial_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtCore/qmath.h> #include <QtQuick/private/qquickflickable_p.h> @@ -122,6 +123,8 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void executeHandle(bool complete = false); + qreal from; qreal to; qreal value; @@ -133,7 +136,7 @@ public: QQuickDial::SnapMode snapMode; bool wrap; bool live; - QQuickItem *handle; + QQuickDeferredPointer<QQuickItem> handle; }; qreal QQuickDialPrivate::valueAt(qreal position) const @@ -253,6 +256,20 @@ void QQuickDialPrivate::handleUngrab() q->setPressed(false); } +static inline QString handleName() { return QStringLiteral("handle"); } + +void QQuickDialPrivate::executeHandle(bool complete) +{ + Q_Q(QQuickDial); + if (handle.wasExecuted()) + return; + + if (!handle) + quickBeginDeferred(q, handleName(), handle); + if (complete) + quickCompleteDeferred(q, handleName(), handle); +} + QQuickDial::QQuickDial(QQuickItem *parent) : QQuickControl(*(new QQuickDialPrivate), parent) { @@ -524,7 +541,9 @@ void QQuickDial::setPressed(bool pressed) */ QQuickItem *QQuickDial::handle() const { - Q_D(const QQuickDial); + QQuickDialPrivate *d = const_cast<QQuickDialPrivate *>(d_func()); + if (!d->handle) + d->executeHandle(); return d->handle; } @@ -534,11 +553,12 @@ void QQuickDial::setHandle(QQuickItem *handle) if (handle == d->handle) return; - QQuickControlPrivate::destroyDelegate(d->handle, this); + delete d->handle; d->handle = handle; if (d->handle && !d->handle->parentItem()) d->handle->setParentItem(this); - emit handleChanged(); + if (!d->handle.isExecuting()) + emit handleChanged(); } /*! @@ -730,6 +750,7 @@ void QQuickDial::mirrorChange() void QQuickDial::componentComplete() { Q_D(QQuickDial); + d->executeHandle(true); QQuickControl::componentComplete(); setValue(d->value); d->updatePosition(); diff --git a/src/quicktemplates2/qquickdial_p.h b/src/quicktemplates2/qquickdial_p.h index 296f7986..d7bab0ad 100644 --- a/src/quicktemplates2/qquickdial_p.h +++ b/src/quicktemplates2/qquickdial_p.h @@ -72,6 +72,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDial : public QQuickControl Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) // 2.2 (Qt 5.9) Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2) + Q_CLASSINFO("DeferredPropertyNames", "background,handle") public: explicit QQuickDial(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index c227afdc..c127192c 100644 --- a/src/quicktemplates2/qquickgroupbox.cpp +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -36,6 +36,7 @@ #include "qquickgroupbox_p.h" #include "qquickframe_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtGui/qpa/qplatformtheme.h> @@ -85,13 +86,31 @@ QT_BEGIN_NAMESPACE class QQuickGroupBoxPrivate : public QQuickFramePrivate { + Q_DECLARE_PUBLIC(QQuickGroupBox) + public: QQuickGroupBoxPrivate() : label(nullptr) { } + void executeLabel(bool complete = false); + QString title; - QQuickItem *label; + QQuickDeferredPointer<QQuickItem> label; }; +static inline QString labelName() { return QStringLiteral("label"); } + +void QQuickGroupBoxPrivate::executeLabel(bool complete) +{ + Q_Q(QQuickGroupBox); + if (label.wasExecuted()) + return; + + if (!label) + quickBeginDeferred(q, labelName(), label); + if (complete) + quickCompleteDeferred(q, labelName(), label); +} + QQuickGroupBox::QQuickGroupBox(QQuickItem *parent) : QQuickFrame(*(new QQuickGroupBoxPrivate), parent) { @@ -131,7 +150,9 @@ void QQuickGroupBox::setTitle(const QString &title) */ QQuickItem *QQuickGroupBox::label() const { - Q_D(const QQuickGroupBox); + QQuickGroupBoxPrivate *d = const_cast<QQuickGroupBoxPrivate *>(d_func()); + if (!d->label) + d->executeLabel(); return d->label; } @@ -141,11 +162,19 @@ void QQuickGroupBox::setLabel(QQuickItem *label) if (d->label == label) return; - QQuickControlPrivate::destroyDelegate(d->label, this); + delete d->label; d->label = label; if (label && !label->parentItem()) label->setParentItem(this); - emit labelChanged(); + if (!d->label.isExecuting()) + emit labelChanged(); +} + +void QQuickGroupBox::componentComplete() +{ + Q_D(QQuickGroupBox); + d->executeLabel(true); + QQuickFrame::componentComplete(); } QFont QQuickGroupBox::defaultFont() const diff --git a/src/quicktemplates2/qquickgroupbox_p.h b/src/quicktemplates2/qquickgroupbox_p.h index b74389e4..b46d91fd 100644 --- a/src/quicktemplates2/qquickgroupbox_p.h +++ b/src/quicktemplates2/qquickgroupbox_p.h @@ -59,6 +59,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickGroupBox : public QQuickFrame Q_OBJECT Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) Q_PROPERTY(QQuickItem *label READ label WRITE setLabel NOTIFY labelChanged FINAL) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,label") public: explicit QQuickGroupBox(QQuickItem *parent = nullptr); @@ -74,6 +75,8 @@ Q_SIGNALS: void labelChanged(); protected: + void componentComplete() override; + QFont defaultFont() const override; QPalette defaultPalette() const override; diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index 724fd086..d27393ae 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -38,6 +38,7 @@ #include "qquicklabel_p_p.h" #include "qquickcontrol_p.h" #include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquicktext_p.h> @@ -202,6 +203,20 @@ QAccessible::Role QQuickLabelPrivate::accessibleRole() const } #endif +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickLabelPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickLabel); + if (background.wasExecuted()) + return; + + if (!background) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + QQuickLabel::QQuickLabel(QQuickItem *parent) : QQuickText(*(new QQuickLabelPrivate), parent) { @@ -237,7 +252,9 @@ void QQuickLabel::setFont(const QFont &font) */ QQuickItem *QQuickLabel::background() const { - Q_D(const QQuickLabel); + QQuickLabelPrivate *d = const_cast<QQuickLabelPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -247,14 +264,15 @@ void QQuickLabel::setBackground(QQuickItem *background) if (d->background == background) return; - QQuickControlPrivate::destroyDelegate(d->background, this); + delete d->background; d->background = background; if (background) { background->setParentItem(this); if (qFuzzyIsNull(background->z())) background->setZ(-1); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -300,6 +318,7 @@ void QQuickLabel::classBegin() void QQuickLabel::componentComplete() { Q_D(QQuickLabel); + d->executeBackground(true); QQuickText::componentComplete(); #if QT_CONFIG(accessibility) if (QAccessible::isActive()) diff --git a/src/quicktemplates2/qquicklabel_p.h b/src/quicktemplates2/qquicklabel_p.h index 937c57eb..5486d311 100644 --- a/src/quicktemplates2/qquicklabel_p.h +++ b/src/quicktemplates2/qquicklabel_p.h @@ -63,6 +63,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickLabel : public QQuickText Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickLabel(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h index a8214d77..5f432a22 100644 --- a/src/quicktemplates2/qquicklabel_p_p.h +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -50,6 +50,7 @@ #include <QtQml/private/qlazilyallocated_p.h> #include <QtQuick/private/qquicktext_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> #if QT_CONFIG(accessibility) #include <QtGui/qaccessible.h> @@ -98,6 +99,8 @@ public: QAccessible::Role accessibleRole() const override; #endif + void executeBackground(bool complete = false); + struct ExtraData { QFont requestedFont; QPalette requestedPalette; @@ -105,7 +108,7 @@ public: QLazilyAllocated<ExtraData> extra; QPalette resolvedPalette; - QQuickItem *background; + QQuickDeferredPointer<QQuickItem> background; }; QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 50050df3..907b01e9 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -106,9 +106,9 @@ QQuickPagePrivate::QQuickPagePrivate() QQuickItem *QQuickPagePrivate::getContentItem() { Q_Q(QQuickPage); - if (!contentItem) - return new QQuickItem(q); - return contentItem; + if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + return item; + return new QQuickItem(q); } QQuickPage::QQuickPage(QQuickItem *parent) diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index b89131c4..4c3e1422 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -113,9 +113,9 @@ QQuickPanePrivate::QQuickPanePrivate() QQuickItem *QQuickPanePrivate::getContentItem() { Q_Q(QQuickPane); - if (!contentItem) - return new QQuickItem(q); - return contentItem; + if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + return item; + return new QQuickItem(q); } QQuickPane::QQuickPane(QQuickItem *parent) diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index 27528f2f..af4d03a4 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -104,9 +104,9 @@ void QQuickPopupItemPrivate::resolvePalette() QQuickItem *QQuickPopupItemPrivate::getContentItem() { Q_Q(QQuickPopupItem); - if (!contentItem) - return new QQuickItem(q); - return contentItem; + if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + return item; + return new QQuickItem(q); } QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index d16cd3b4..937de9c9 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -36,6 +36,7 @@ #include "qquickrangeslider_p.h" #include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtCore/qscopedpointer.h> #include <QtQuick/private/qquickwindow_p.h> @@ -109,13 +110,15 @@ public: void setPosition(qreal position, bool ignoreOtherPosition = false); void updatePosition(bool ignoreOtherPosition = false); + void executeHandle(bool complete = false); + static QQuickRangeSliderNodePrivate *get(QQuickRangeSliderNode *node); qreal value; bool isPendingValue; qreal pendingValue; qreal position; - QQuickItem *handle; + QQuickDeferredPointer<QQuickItem> handle; QQuickRangeSlider *slider; bool pressed; bool hovered; @@ -149,6 +152,20 @@ void QQuickRangeSliderNodePrivate::updatePosition(bool ignoreOtherPosition) setPosition(pos, ignoreOtherPosition); } +static inline QString handleName() { return QStringLiteral("handle"); } + +void QQuickRangeSliderNodePrivate::executeHandle(bool complete) +{ + Q_Q(QQuickRangeSliderNode); + if (handle.wasExecuted()) + return; + + if (!handle) + quickBeginDeferred(q, handleName(), handle); + if (complete) + quickCompleteDeferred(q, handleName(), handle); +} + QQuickRangeSliderNodePrivate *QQuickRangeSliderNodePrivate::get(QQuickRangeSliderNode *node) { return node->d_func(); @@ -227,7 +244,9 @@ qreal QQuickRangeSliderNode::visualPosition() const QQuickItem *QQuickRangeSliderNode::handle() const { - Q_D(const QQuickRangeSliderNode); + QQuickRangeSliderNodePrivate *d = const_cast<QQuickRangeSliderNodePrivate *>(d_func()); + if (!d->handle) + d->executeHandle(); return d->handle; } @@ -237,7 +256,7 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) if (d->handle == handle) return; - QQuickControlPrivate::destroyDelegate(d->handle, d->slider); + delete d->handle; d->handle = handle; if (handle) { if (!handle->parentItem()) @@ -263,7 +282,8 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) handle->setActiveFocusOnTab(true); } - emit handleChanged(); + if (!d->handle.isExecuting()) + emit handleChanged(); } bool QQuickRangeSliderNode::isPressed() const @@ -1077,13 +1097,27 @@ void QQuickRangeSlider::mirrorChange() emit d->second->visualPositionChanged(); } -void QQuickRangeSlider::componentComplete() +void QQuickRangeSlider::classBegin() { Q_D(QQuickRangeSlider); - QQuickControl::componentComplete(); + QQuickControl::classBegin(); + QQmlContext *context = qmlContext(this); + if (context) { + QQmlEngine::setContextForObject(d->first, context); + QQmlEngine::setContextForObject(d->second, context); + } +} + +void QQuickRangeSlider::componentComplete() +{ + Q_D(QQuickRangeSlider); QQuickRangeSliderNodePrivate *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first); QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second); + firstPrivate->executeHandle(true); + secondPrivate->executeHandle(true); + + QQuickControl::componentComplete(); if (firstPrivate->isPendingValue || secondPrivate->isPendingValue || !qFuzzyCompare(d->from, defaultFrom) || !qFuzzyCompare(d->to, defaultTo)) { diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h index ef6e5677..a6326441 100644 --- a/src/quicktemplates2/qquickrangeslider_p.h +++ b/src/quicktemplates2/qquickrangeslider_p.h @@ -131,6 +131,7 @@ protected: void touchEvent(QTouchEvent *event) override; #endif void mirrorChange() override; + void classBegin() override; void componentComplete() override; #if QT_CONFIG(accessibility) @@ -156,6 +157,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSliderNode : public QObject Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) // 2.1 (Qt 5.8) Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1) + Q_CLASSINFO("DeferredPropertyNames", "handle") public: explicit QQuickRangeSliderNode(qreal value, QQuickRangeSlider *slider); diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp index fa9a6c3b..254a90d7 100644 --- a/src/quicktemplates2/qquickscrollview.cpp +++ b/src/quicktemplates2/qquickscrollview.cpp @@ -146,6 +146,8 @@ QQuickScrollViewPrivate::QQuickScrollViewPrivate() QQuickItem *QQuickScrollViewPrivate::getContentItem() { + if (!contentItem) + executeContentItem(); return ensureFlickable(false); } diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp index b44c723b..b491cab2 100644 --- a/src/quicktemplates2/qquickshortcutcontext.cpp +++ b/src/quicktemplates2/qquickshortcutcontext.cpp @@ -42,6 +42,7 @@ #include "qquickmenubaritem_p.h" #include <QtGui/qguiapplication.h> +#include <QtQuick/qquickrendercontrol.h> QT_BEGIN_NAMESPACE @@ -84,6 +85,8 @@ bool QQuickShortcutContext::matcher(QObject *obj, Qt::ShortcutContext context) item = popup->popupItem(); } } + if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(obj))) + obj = renderWindow; return obj && obj == QGuiApplication::focusWindow() && !isBlockedByPopup(item); default: return false; diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index b358663d..21aeda39 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -36,6 +36,7 @@ #include "qquickslider_p.h" #include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtQuick/private/qquickwindow_p.h> @@ -112,6 +113,8 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void executeHandle(bool complete = false); + qreal from; qreal to; qreal value; @@ -122,7 +125,7 @@ public: QPointF pressPoint; Qt::Orientation orientation; QQuickSlider::SnapMode snapMode; - QQuickItem *handle; + QQuickDeferredPointer<QQuickItem> handle; }; qreal QQuickSliderPrivate::snapPosition(qreal position) const @@ -235,6 +238,20 @@ void QQuickSliderPrivate::handleUngrab() q->setPressed(false); } +static inline QString handleName() { return QStringLiteral("handle"); } + +void QQuickSliderPrivate::executeHandle(bool complete) +{ + Q_Q(QQuickSlider); + if (handle.wasExecuted()) + return; + + if (!handle) + quickBeginDeferred(q, handleName(), handle); + if (complete) + quickCompleteDeferred(q, handleName(), handle); +} + QQuickSlider::QQuickSlider(QQuickItem *parent) : QQuickControl(*(new QQuickSliderPrivate), parent) { @@ -517,7 +534,9 @@ void QQuickSlider::setOrientation(Qt::Orientation orientation) */ QQuickItem *QQuickSlider::handle() const { - Q_D(const QQuickSlider); + QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func()); + if (!d->handle) + d->executeHandle(); return d->handle; } @@ -527,11 +546,12 @@ void QQuickSlider::setHandle(QQuickItem *handle) if (d->handle == handle) return; - QQuickControlPrivate::destroyDelegate(d->handle, this); + delete d->handle; d->handle = handle; if (handle && !handle->parentItem()) handle->setParentItem(this); - emit handleChanged(); + if (!d->handle.isExecuting()) + emit handleChanged(); } /*! @@ -736,6 +756,7 @@ void QQuickSlider::mirrorChange() void QQuickSlider::componentComplete() { Q_D(QQuickSlider); + d->executeHandle(true); QQuickControl::componentComplete(); setValue(d->value); d->updatePosition(); diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h index b2f4897c..95545462 100644 --- a/src/quicktemplates2/qquickslider_p.h +++ b/src/quicktemplates2/qquickslider_p.h @@ -71,6 +71,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl // 2.3 (Qt 5.10) Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION 3) Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background,handle") public: explicit QQuickSlider(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index ef1c9d97..27dd0d5e 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -36,6 +36,7 @@ #include "qquickspinbox_p.h" #include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtGui/qguiapplication.h> #include <QtGui/qstylehints.h> @@ -162,6 +163,30 @@ public: Qt::InputMethodHints inputMethodHints; }; +class QQuickSpinButtonPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSpinButton) + +public: + QQuickSpinButtonPrivate() + : pressed(false), + hovered(false), + indicator(nullptr) + { + } + + static QQuickSpinButtonPrivate *get(QQuickSpinButton *button) + { + return button->d_func(); + } + + void executeIndicator(bool complete = false); + + bool pressed; + bool hovered; + QQuickDeferredPointer<QQuickItem> indicator; +}; + int QQuickSpinBoxPrivate::boundValue(int value, bool wrap) const { bool inverted = from > to; @@ -880,9 +905,24 @@ void QQuickSpinBox::wheelEvent(QWheelEvent *event) } #endif +void QQuickSpinBox::classBegin() +{ + Q_D(QQuickSpinBox); + QQuickControl::classBegin(); + + QQmlContext *context = qmlContext(this); + if (context) { + QQmlEngine::setContextForObject(d->up, context); + QQmlEngine::setContextForObject(d->down, context); + } +} + void QQuickSpinBox::componentComplete() { Q_D(QQuickSpinBox); + QQuickSpinButtonPrivate::get(d->up)->executeIndicator(true); + QQuickSpinButtonPrivate::get(d->down)->executeIndicator(true); + QQuickControl::componentComplete(); if (!d->setValue(d->value, /* allowWrap = */ false, /* modified = */ false)) { d->updateUpEnabled(); @@ -906,6 +946,8 @@ void QQuickSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) if (newItem) { newItem->setActiveFocusOnTab(true); + if (d->activeFocus) + newItem->forceActiveFocus(d->focusReason); #if QT_CONFIG(cursor) if (d->editable) newItem->setCursor(Qt::IBeamCursor); @@ -942,20 +984,19 @@ void QQuickSpinBox::accessibilityActiveChanged(bool active) } #endif -class QQuickSpinButtonPrivate : public QObjectPrivate +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickSpinButtonPrivate::executeIndicator(bool complete) { -public: - QQuickSpinButtonPrivate() - : pressed(false), - hovered(false), - indicator(nullptr) - { - } + Q_Q(QQuickSpinButton); + if (indicator.wasExecuted()) + return; - bool pressed; - bool hovered; - QQuickItem *indicator; -}; + if (!indicator) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} QQuickSpinButton::QQuickSpinButton(QQuickSpinBox *parent) : QObject(*(new QQuickSpinButtonPrivate), parent) @@ -980,7 +1021,9 @@ void QQuickSpinButton::setPressed(bool pressed) QQuickItem *QQuickSpinButton::indicator() const { - Q_D(const QQuickSpinButton); + QQuickSpinButtonPrivate *d = const_cast<QQuickSpinButtonPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -990,14 +1033,15 @@ void QQuickSpinButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; - QQuickControlPrivate::destroyDelegate(d->indicator, d->parent); + delete d->indicator; d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) indicator->setParentItem(static_cast<QQuickItem *>(parent())); } - emit indicatorChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); } bool QQuickSpinButton::isHovered() const diff --git a/src/quicktemplates2/qquickspinbox_p.h b/src/quicktemplates2/qquickspinbox_p.h index 6485c053..524930a2 100644 --- a/src/quicktemplates2/qquickspinbox_p.h +++ b/src/quicktemplates2/qquickspinbox_p.h @@ -149,6 +149,7 @@ protected: void wheelEvent(QWheelEvent *event) override; #endif + void classBegin() override; void componentComplete() override; void itemChange(ItemChange change, const ItemChangeData &value) override; void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; @@ -173,6 +174,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinButton : public QObject Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) // 2.1 (Qt 5.8) Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1) + Q_CLASSINFO("DeferredPropertyNames", "indicator") public: explicit QQuickSpinButton(QQuickSpinBox *parent); diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 02e84a35..d2458c24 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -39,6 +39,7 @@ #include "qquickcontrol_p.h" #include "qquickcontrol_p_p.h" #include "qquickscrollview_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtQml/qqmlinfo.h> #include <QtQuick/private/qquickitem_p.h> @@ -437,6 +438,20 @@ QAccessible::Role QQuickTextAreaPrivate::accessibleRole() const } #endif +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickTextAreaPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickTextArea); + if (background.wasExecuted()) + return; + + if (!background) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + QQuickTextArea::QQuickTextArea(QQuickItem *parent) : QQuickTextEdit(*(new QQuickTextAreaPrivate), parent) { @@ -490,7 +505,9 @@ void QQuickTextArea::setFont(const QFont &font) */ QQuickItem *QQuickTextArea::background() const { - Q_D(const QQuickTextArea); + QQuickTextAreaPrivate *d = const_cast<QQuickTextAreaPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -500,7 +517,7 @@ void QQuickTextArea::setBackground(QQuickItem *background) if (d->background == background) return; - QQuickControlPrivate::destroyDelegate(d->background, this); + delete d->background; d->background = background; if (background) { background->setParentItem(this); @@ -509,7 +526,8 @@ void QQuickTextArea::setBackground(QQuickItem *background) if (isComponentComplete()) d->resizeBackground(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -686,6 +704,7 @@ void QQuickTextArea::classBegin() void QQuickTextArea::componentComplete() { Q_D(QQuickTextArea); + d->executeBackground(true); QQuickTextEdit::componentComplete(); #if QT_CONFIG(quicktemplates2_hover) if (!d->explicitHoverEnabled) diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h index 26799532..5482ceae 100644 --- a/src/quicktemplates2/qquicktextarea_p.h +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -73,6 +73,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickTextArea(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h index 32f53c4f..d27af8f6 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -52,6 +52,7 @@ #include <QtQuick/private/qquicktextedit_p_p.h> #include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQuickTemplates2/private/qquickpresshandler_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> #include <QtQuickTemplates2/private/qquicktextarea_p.h> @@ -124,6 +125,8 @@ public: QAccessible::Role accessibleRole() const override; #endif + void executeBackground(bool complete = false); + #if QT_CONFIG(quicktemplates2_hover) bool hovered; bool explicitHoverEnabled; @@ -136,7 +139,7 @@ public: QLazilyAllocated<ExtraData> extra; QPalette resolvedPalette; - QQuickItem *background; + QQuickDeferredPointer<QQuickItem> background; QString placeholder; Qt::FocusReason focusReason; QQuickPressHandler pressHandler; diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index fba0e67c..03da9323 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -38,6 +38,7 @@ #include "qquicktextfield_p_p.h" #include "qquickcontrol_p.h" #include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquicktextinput_p.h> @@ -311,6 +312,20 @@ QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const } #endif +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickTextFieldPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickTextField); + if (background.wasExecuted()) + return; + + if (!background) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + QQuickTextField::QQuickTextField(QQuickItem *parent) : QQuickTextInput(*(new QQuickTextFieldPrivate), parent) { @@ -352,7 +367,9 @@ void QQuickTextField::setFont(const QFont &font) */ QQuickItem *QQuickTextField::background() const { - Q_D(const QQuickTextField); + QQuickTextFieldPrivate *d = const_cast<QQuickTextFieldPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -362,7 +379,7 @@ void QQuickTextField::setBackground(QQuickItem *background) if (d->background == background) return; - QQuickControlPrivate::destroyDelegate(d->background, this); + delete d->background; d->background = background; if (background) { background->setParentItem(this); @@ -371,7 +388,8 @@ void QQuickTextField::setBackground(QQuickItem *background) if (isComponentComplete()) d->resizeBackground(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -540,6 +558,7 @@ void QQuickTextField::classBegin() void QQuickTextField::componentComplete() { Q_D(QQuickTextField); + d->executeBackground(true); QQuickTextInput::componentComplete(); #if QT_CONFIG(quicktemplates2_hover) if (!d->explicitHoverEnabled) diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h index 7dab0caf..4757bd2d 100644 --- a/src/quicktemplates2/qquicktextfield_p.h +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -72,6 +72,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickTextField(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h index 65767452..5ae79b7f 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -51,6 +51,7 @@ #include <QtQml/private/qlazilyallocated_p.h> #include <QtQuick/private/qquicktextinput_p_p.h> #include <QtQuickTemplates2/private/qquickpresshandler_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> #include <QtQuickTemplates2/private/qquicktextfield_p.h> @@ -112,6 +113,8 @@ public: QAccessible::Role accessibleRole() const override; #endif + void executeBackground(bool complete = false); + #if QT_CONFIG(quicktemplates2_hover) bool hovered; bool explicitHoverEnabled; @@ -124,7 +127,7 @@ public: QLazilyAllocated<ExtraData> extra; QPalette resolvedPalette; - QQuickItem *background; + QQuickDeferredPointer<QQuickItem> background; QString placeholder; Qt::FocusReason focusReason; QQuickPressHandler pressHandler; diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h index 5d4df4a7..c388c28d 100644 --- a/src/quicktemplates2/qquicktumbler_p.h +++ b/src/quicktemplates2/qquicktumbler_p.h @@ -70,6 +70,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumbler : public QQuickControl Q_PROPERTY(bool wrap READ wrap WRITE setWrap RESET resetWrap NOTIFY wrapChanged FINAL REVISION 1) // 2.2 (Qt 5.9) Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged FINAL REVISION 2) + Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickTumbler(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index a90b4f94..ee51f995 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -17,6 +17,8 @@ HEADERS += \ $$PWD/qquickcontainer_p_p.h \ $$PWD/qquickcontrol_p.h \ $$PWD/qquickcontrol_p_p.h \ + $$PWD/qquickdeferredexecute_p_p.h \ + $$PWD/qquickdeferredpointer_p_p.h \ $$PWD/qquickdelaybutton_p.h \ $$PWD/qquickdial_p.h \ $$PWD/qquickdialog_p.h \ @@ -102,6 +104,7 @@ SOURCES += \ $$PWD/qquickcombobox.cpp \ $$PWD/qquickcontainer.cpp \ $$PWD/qquickcontrol.cpp \ + $$PWD/qquickdeferredexecute.cpp \ $$PWD/qquickdelaybutton.cpp \ $$PWD/qquickdial.cpp \ $$PWD/qquickdialog.cpp \ |