aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-12-19 13:38:40 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2017-12-21 14:46:30 +0000
commitc40486acc352d49398186fa32d1ccabdd5fc83c6 (patch)
treeb4f77d072020eef0bb17d4491e98daa1a048537a /src
parent1e33020fc02b56001d805d3d66badd41480b746d (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')
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp13
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h1
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp12
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp25
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp22
-rw-r--r--src/quicktemplates2/qquickcontrol_p_p.h3
-rw-r--r--src/quicktemplates2/qquickdeferredexecute.cpp32
-rw-r--r--src/quicktemplates2/qquickdeferredexecute_p_p.h9
-rw-r--r--src/quicktemplates2/qquickdial.cpp12
-rw-r--r--src/quicktemplates2/qquickgroupbox.cpp12
-rw-r--r--src/quicktemplates2/qquicklabel.cpp11
-rw-r--r--src/quicktemplates2/qquicklabel_p_p.h1
-rw-r--r--src/quicktemplates2/qquickpopupitem.cpp17
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp16
-rw-r--r--src/quicktemplates2/qquickslider.cpp12
-rw-r--r--src/quicktemplates2/qquickspinbox.cpp12
-rw-r--r--src/quicktemplates2/qquicktextarea.cpp11
-rw-r--r--src/quicktemplates2/qquicktextarea_p_p.h1
-rw-r--r--src/quicktemplates2/qquicktextfield.cpp11
-rw-r--r--src/quicktemplates2/qquicktextfield_p_p.h1
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)