diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-12-19 13:38:40 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-12-21 14:46:30 +0000 |
commit | c40486acc352d49398186fa32d1ccabdd5fc83c6 (patch) | |
tree | b4f77d072020eef0bb17d4491e98daa1a048537a /src | |
parent | 1e33020fc02b56001d805d3d66badd41480b746d (diff) |
Fix deferred execution
If the QML engine refuses to defer execution of a delegate (it contains
an ID), we must make sure to cancel any pending deferred execution for
the same delegate. Otherwise, we may end up overriding a custom (non-
deferred) delegate with a default (deferred) delegate.
This patch adds a new test style "identified" to tst_customization.
This style contains delegates with IDs so we can test the behavior with
IDs in base styles. Furthermore, overriding delegates is now tested
in various ways (with and without IDs in the base and custom styles) in
a separate test method. This is done by generating QML code to override
delegates with dummy Item instances with appropriate IDs and names.
Task-number: QTBUG-65341
Change-Id: Ie6dca287cb74672004d9d8f599760b9d32c3a380
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src')
20 files changed, 204 insertions, 30 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 45ade7bb..af676a50 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -261,13 +261,19 @@ void QQuickAbstractButtonPrivate::toggle(bool value) static inline QString indicatorName() { return QStringLiteral("indicator"); } +void QQuickAbstractButtonPrivate::cancelIndicator() +{ + Q_Q(QQuickAbstractButton); + quickCancelDeferred(q, indicatorName()); +} + void QQuickAbstractButtonPrivate::executeIndicator(bool complete) { - Q_Q(QQuickControl); + Q_Q(QQuickAbstractButton); if (indicator.wasExecuted()) return; - if (!indicator) + if (!indicator || complete) quickBeginDeferred(q, indicatorName(), indicator); if (complete) quickCompleteDeferred(q, indicatorName(), indicator); @@ -572,6 +578,9 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + delete d->indicator; d->indicator = indicator; if (indicator) { diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index 6634971e..07e6d3f2 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -85,6 +85,7 @@ public: void toggle(bool value); + void cancelIndicator(); void executeIndicator(bool complete = false); QString text; diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index c1a7f301..b07b2142 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -175,6 +175,7 @@ public: static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + void cancelBackground(); void executeBackground(bool complete = false); bool complete; @@ -301,13 +302,19 @@ void QQuickApplicationWindowPrivate::contentData_append(QQmlListProperty<QObject static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickApplicationWindowPrivate::cancelBackground() +{ + Q_Q(QQuickApplicationWindow); + quickCancelDeferred(q, backgroundName()); +} + void QQuickApplicationWindowPrivate::executeBackground(bool complete) { Q_Q(QQuickApplicationWindow); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -366,6 +373,9 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index d221b9bc..fb10730e 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -253,7 +253,10 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void cancelIndicator(); void executeIndicator(bool complete = false); + + void cancelPopup(); void executePopup(bool complete = false); bool flat; @@ -671,13 +674,19 @@ void QQuickComboBoxPrivate::handleUngrab() static inline QString indicatorName() { return QStringLiteral("indicator"); } +void QQuickComboBoxPrivate::cancelIndicator() +{ + Q_Q(QQuickComboBox); + quickCancelDeferred(q, indicatorName()); +} + void QQuickComboBoxPrivate::executeIndicator(bool complete) { Q_Q(QQuickComboBox); if (indicator.wasExecuted()) return; - if (!indicator) + if (!indicator || complete) quickBeginDeferred(q, indicatorName(), indicator); if (complete) quickCompleteDeferred(q, indicatorName(), indicator); @@ -685,13 +694,19 @@ void QQuickComboBoxPrivate::executeIndicator(bool complete) static inline QString popupName() { return QStringLiteral("popup"); } +void QQuickComboBoxPrivate::cancelPopup() +{ + Q_Q(QQuickComboBox); + quickCancelDeferred(q, popupName()); +} + void QQuickComboBoxPrivate::executePopup(bool complete) { Q_Q(QQuickComboBox); if (popup.wasExecuted()) return; - if (!popup) + if (!popup || complete) quickBeginDeferred(q, popupName(), popup); if (complete) quickCompleteDeferred(q, popupName(), popup); @@ -1015,6 +1030,9 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + delete d->indicator; d->indicator = indicator; if (indicator) { @@ -1052,6 +1070,9 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) if (d->popup == popup) return; + if (!d->popup.isExecuting()) + d->cancelPopup(); + if (d->popup) { QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); delete d->popup; diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index cfecc67c..6fbd4c07 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -292,6 +292,9 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) if (contentItem == item) return; + if (!contentItem.isExecuting()) + cancelContentItem(); + q->contentItemChange(item, contentItem); delete contentItem; contentItem = item; @@ -938,13 +941,19 @@ QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item) static inline QString contentItemName() { return QStringLiteral("contentItem"); } +void QQuickControlPrivate::cancelContentItem() +{ + Q_Q(QQuickControl); + quickCancelDeferred(q, contentItemName()); +} + void QQuickControlPrivate::executeContentItem(bool complete) { Q_Q(QQuickControl); if (contentItem.wasExecuted()) return; - if (!contentItem) + if (!contentItem || complete) quickBeginDeferred(q, contentItemName(), contentItem); if (complete) quickCompleteDeferred(q, contentItemName(), contentItem); @@ -952,13 +961,19 @@ void QQuickControlPrivate::executeContentItem(bool complete) static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickControlPrivate::cancelBackground() +{ + Q_Q(QQuickControl); + quickCancelDeferred(q, backgroundName()); +} + void QQuickControlPrivate::executeBackground(bool complete) { Q_Q(QQuickControl); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -1257,6 +1272,9 @@ void QQuickControl::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 81fa03a4..3ed8b637 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -127,7 +127,10 @@ public: static bool calcHoverEnabled(const QQuickItem *item); #endif + virtual void cancelContentItem(); virtual void executeContentItem(bool complete = false); + + virtual void cancelBackground(); virtual void executeBackground(bool complete = false); static void destroyDelegate(QObject *object, QObject *parent); diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp index 802ed3d0..ca6953bc 100644 --- a/src/quicktemplates2/qquickdeferredexecute.cpp +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -55,13 +55,24 @@ static inline uint qHash(QObject *object, const QString &propertyName) Q_GLOBAL_STATIC(DeferredStates, deferredStates) -static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState) +static void cancelDeferred(QObject *object, int propertyIndex) +{ + QQmlData *ddata = QQmlData::get(object); + auto dit = ddata->deferredData.rbegin(); + while (dit != ddata->deferredData.rend()) { + (*dit)->bindings.remove(propertyIndex); + ++dit; + } +} + +static bool 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(); + int wasInProgress = enginePriv->inProgressCreations; for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) { QQmlData::DeferredData *deferData = *dit; @@ -91,12 +102,11 @@ static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro // 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; - } + cancelDeferred(object, propertyIndex); break; } + + return enginePriv->inProgressCreations > wasInProgress; } void beginDeferred(QObject *object, const QString &property) @@ -106,15 +116,21 @@ void beginDeferred(QObject *object, const QString &property) QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine); QQmlComponentPrivate::DeferredState *state = new QQmlComponentPrivate::DeferredState; - beginDeferred(ep, QQmlProperty(object, property), state); + if (beginDeferred(ep, QQmlProperty(object, property), state)) + deferredStates()->insert(qHash(object, property), state); + else + delete state; // Release deferred data for those compilation units that no longer have deferred bindings data->releaseDeferredData(); - - deferredStates()->insert(qHash(object, property), state); } } +void cancelDeferred(QObject *object, const QString &property) +{ + cancelDeferred(object, QQmlProperty(object, property).index()); +} + void completeDeferred(QObject *object, const QString &property) { QQmlData *data = QQmlData::get(object); diff --git a/src/quicktemplates2/qquickdeferredexecute_p_p.h b/src/quicktemplates2/qquickdeferredexecute_p_p.h index 87124e48..400c5734 100644 --- a/src/quicktemplates2/qquickdeferredexecute_p_p.h +++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h @@ -58,25 +58,28 @@ class QObject; namespace QtQuickPrivate { void beginDeferred(QObject *object, const QString &property); + void cancelDeferred(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); } +inline void quickCancelDeferred(QObject *object, const QString &property) +{ + QtQuickPrivate::cancelDeferred(object, property); +} + 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(); } diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index 964cefe1..b5957069 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -123,6 +123,7 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void cancelHandle(); void executeHandle(bool complete = false); qreal from; @@ -258,13 +259,19 @@ void QQuickDialPrivate::handleUngrab() static inline QString handleName() { return QStringLiteral("handle"); } +void QQuickDialPrivate::cancelHandle() +{ + Q_Q(QQuickDial); + quickCancelDeferred(q, handleName()); +} + void QQuickDialPrivate::executeHandle(bool complete) { Q_Q(QQuickDial); if (handle.wasExecuted()) return; - if (!handle) + if (!handle || complete) quickBeginDeferred(q, handleName(), handle); if (complete) quickCompleteDeferred(q, handleName(), handle); @@ -553,6 +560,9 @@ void QQuickDial::setHandle(QQuickItem *handle) if (handle == d->handle) return; + if (!d->handle.isExecuting()) + d->cancelHandle(); + delete d->handle; d->handle = handle; if (d->handle && !d->handle->parentItem()) diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index 674f5b18..3c7bf715 100644 --- a/src/quicktemplates2/qquickgroupbox.cpp +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -91,6 +91,7 @@ class QQuickGroupBoxPrivate : public QQuickFramePrivate public: QQuickGroupBoxPrivate() : label(nullptr) { } + void cancelLabel(); void executeLabel(bool complete = false); QString title; @@ -99,13 +100,19 @@ public: static inline QString labelName() { return QStringLiteral("label"); } +void QQuickGroupBoxPrivate::cancelLabel() +{ + Q_Q(QQuickGroupBox); + quickCancelDeferred(q, labelName()); +} + void QQuickGroupBoxPrivate::executeLabel(bool complete) { Q_Q(QQuickGroupBox); if (label.wasExecuted()) return; - if (!label) + if (!label || complete) quickBeginDeferred(q, labelName(), label); if (complete) quickCompleteDeferred(q, labelName(), label); @@ -162,6 +169,9 @@ void QQuickGroupBox::setLabel(QQuickItem *label) if (d->label == label) return; + if (!d->label.isExecuting()) + d->cancelLabel(); + delete d->label; d->label = label; if (label && !label->parentItem()) diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index 418a7834..c8b125ca 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -158,13 +158,19 @@ QAccessible::Role QQuickLabelPrivate::accessibleRole() const static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickLabelPrivate::cancelBackground() +{ + Q_Q(QQuickLabel); + quickCancelDeferred(q, backgroundName()); +} + void QQuickLabelPrivate::executeBackground(bool complete) { Q_Q(QQuickLabel); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -217,6 +223,9 @@ void QQuickLabel::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h index b8ad2ae7..f612434b 100644 --- a/src/quicktemplates2/qquicklabel_p_p.h +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -85,6 +85,7 @@ public: QAccessible::Role accessibleRole() const override; #endif + void cancelBackground(); void executeBackground(bool complete = false); QFont font; diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index db335a06..96816eac 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -60,7 +60,10 @@ public: QQuickItem *getContentItem() override; + void cancelContentItem() override; void executeContentItem(bool complete = false) override; + + void cancelBackground() override; void executeBackground(bool complete = false) override; int backId; @@ -106,12 +109,17 @@ QQuickItem *QQuickPopupItemPrivate::getContentItem() static inline QString contentItemName() { return QStringLiteral("contentItem"); } +void QQuickPopupItemPrivate::cancelContentItem() +{ + quickCancelDeferred(popup, contentItemName()); +} + void QQuickPopupItemPrivate::executeContentItem(bool complete) { if (contentItem.wasExecuted()) return; - if (!contentItem) + if (!contentItem || complete) quickBeginDeferred(popup, contentItemName(), contentItem); if (complete) quickCompleteDeferred(popup, contentItemName(), contentItem); @@ -119,12 +127,17 @@ void QQuickPopupItemPrivate::executeContentItem(bool complete) static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickPopupItemPrivate::cancelBackground() +{ + quickCancelDeferred(popup, backgroundName()); +} + void QQuickPopupItemPrivate::executeBackground(bool complete) { if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(popup, backgroundName(), background); if (complete) quickCompleteDeferred(popup, backgroundName(), background); diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 51b646ce..557adc3a 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -110,6 +110,7 @@ public: void setPosition(qreal position, bool ignoreOtherPosition = false); void updatePosition(bool ignoreOtherPosition = false); + void cancelHandle(); void executeHandle(bool complete = false); static QQuickRangeSliderNodePrivate *get(QQuickRangeSliderNode *node); @@ -154,13 +155,19 @@ void QQuickRangeSliderNodePrivate::updatePosition(bool ignoreOtherPosition) static inline QString handleName() { return QStringLiteral("handle"); } +void QQuickRangeSliderNodePrivate::cancelHandle() +{ + Q_Q(QQuickRangeSliderNode); + quickCancelDeferred(q, handleName()); +} + void QQuickRangeSliderNodePrivate::executeHandle(bool complete) { Q_Q(QQuickRangeSliderNode); if (handle.wasExecuted()) return; - if (!handle) + if (!handle || complete) quickBeginDeferred(q, handleName(), handle); if (complete) quickCompleteDeferred(q, handleName(), handle); @@ -256,14 +263,17 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) if (d->handle == handle) return; + if (!d->handle.isExecuting()) + d->cancelHandle(); + delete d->handle; d->handle = handle; if (handle) { if (!handle->parentItem()) handle->setParentItem(d->slider); - QQuickItem *firstHandle = d->slider->first()->handle(); - QQuickItem *secondHandle = d->slider->second()->handle(); + QQuickItem *firstHandle = QQuickRangeSliderNodePrivate::get(d->slider->first())->handle; + QQuickItem *secondHandle = QQuickRangeSliderNodePrivate::get(d->slider->second())->handle; if (firstHandle && secondHandle) { // The order of property assignments in QML is undefined, // but we need the first handle to be before the second due diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index 73fa2725..94c9762d 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -113,6 +113,7 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void cancelHandle(); void executeHandle(bool complete = false); qreal from; @@ -240,13 +241,19 @@ void QQuickSliderPrivate::handleUngrab() static inline QString handleName() { return QStringLiteral("handle"); } +void QQuickSliderPrivate::cancelHandle() +{ + Q_Q(QQuickSlider); + quickCancelDeferred(q, handleName()); +} + void QQuickSliderPrivate::executeHandle(bool complete) { Q_Q(QQuickSlider); if (handle.wasExecuted()) return; - if (!handle) + if (!handle || complete) quickBeginDeferred(q, handleName(), handle); if (complete) quickCompleteDeferred(q, handleName(), handle); @@ -514,6 +521,9 @@ void QQuickSlider::setHandle(QQuickItem *handle) if (d->handle == handle) return; + if (!d->handle.isExecuting()) + d->cancelHandle(); + delete d->handle; d->handle = handle; if (handle && !handle->parentItem()) diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 80bef2db..24ec19f8 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -177,6 +177,7 @@ public: return button->d_func(); } + void cancelIndicator(); void executeIndicator(bool complete = false); bool pressed; @@ -934,13 +935,19 @@ void QQuickSpinBox::accessibilityActiveChanged(bool active) static inline QString indicatorName() { return QStringLiteral("indicator"); } +void QQuickSpinButtonPrivate::cancelIndicator() +{ + Q_Q(QQuickSpinButton); + quickCancelDeferred(q, indicatorName()); +} + void QQuickSpinButtonPrivate::executeIndicator(bool complete) { Q_Q(QQuickSpinButton); if (indicator.wasExecuted()) return; - if (!indicator) + if (!indicator || complete) quickBeginDeferred(q, indicatorName(), indicator); if (complete) quickCompleteDeferred(q, indicatorName(), indicator); @@ -981,6 +988,9 @@ void QQuickSpinButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + delete d->indicator; d->indicator = indicator; diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 06867742..500e7bba 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -394,13 +394,19 @@ QAccessible::Role QQuickTextAreaPrivate::accessibleRole() const static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickTextAreaPrivate::cancelBackground() +{ + Q_Q(QQuickTextArea); + quickCancelDeferred(q, backgroundName()); +} + void QQuickTextAreaPrivate::executeBackground(bool complete) { Q_Q(QQuickTextArea); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -471,6 +477,9 @@ void QQuickTextArea::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h index ede9d97f..42ac6fe7 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -109,6 +109,7 @@ public: QAccessible::Role accessibleRole() const override; #endif + void cancelBackground(); void executeBackground(bool complete = false); #if QT_CONFIG(quicktemplates2_hover) diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 2d432ec0..8ca51ddb 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -268,13 +268,19 @@ QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const static inline QString backgroundName() { return QStringLiteral("background"); } +void QQuickTextFieldPrivate::cancelBackground() +{ + Q_Q(QQuickTextField); + quickCancelDeferred(q, backgroundName()); +} + void QQuickTextFieldPrivate::executeBackground(bool complete) { Q_Q(QQuickTextField); if (background.wasExecuted()) return; - if (!background) + if (!background || complete) quickBeginDeferred(q, backgroundName(), background); if (complete) quickCompleteDeferred(q, backgroundName(), background); @@ -333,6 +339,9 @@ void QQuickTextField::setBackground(QQuickItem *background) if (d->background == background) return; + if (!d->background.isExecuting()) + d->cancelBackground(); + delete d->background; d->background = background; if (background) { diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h index 037c6a21..32a79db3 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -98,6 +98,7 @@ public: QAccessible::Role accessibleRole() const override; #endif + void cancelBackground(); void executeBackground(bool complete = false); #if QT_CONFIG(quicktemplates2_hover) |