From ecda8f1ced1400ca399deafba04d1f7a6c55be62 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 16 Nov 2017 14:53:35 +0100 Subject: watch for the actual render window if there is a QQuickRenderControl if the scene is rendered by a QQuickRenderControl and we have a different target window (for instance QQuickWidget) we check the target window of the render control instead of the own window, this fixes window keyboard shortcuts for QQuickWidget Task-number: QTBUG-64548 Change-Id: I7614be580f2a707c752189e4c9b53a5d5f0159d7 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquickshortcutcontext.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp index 6553beb4..92e4c04a 100644 --- a/src/quicktemplates2/qquickshortcutcontext.cpp +++ b/src/quicktemplates2/qquickshortcutcontext.cpp @@ -40,6 +40,7 @@ #include "qquickpopup_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -77,6 +78,8 @@ bool QQuickShortcutContext::matcher(QObject *obj, Qt::ShortcutContext context) item = popup->popupItem(); } } + if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(qobject_cast(obj))) + obj = renderWindow; return obj && obj == QGuiApplication::focusWindow() && !isBlockedByPopup(item); default: return false; -- cgit v1.2.3 From 458eb65f730178bc93ba7b18f0e4dd2a13efad2e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 6 Sep 2017 12:48:55 +0200 Subject: Buttons: defer the execution of the delegates In practice, deferring the execution of the delegates (until accessed) means that the default delegate item does not get created at all, when a custom control replaces it at construction time. Button { background: Rectangle { ... } } Before, such custom Button would never be faster than the original one, because the default delegate was first created and then thrown away at construction time. Originally, this was not considered a huge problem, because the plan was to keep the default delegates so light- weight that it wouldn't matter. However, then came the fancy styles with shadows and effects and thus, heavier default delegates. There's also a growing demand for more features, and the default delegates are slowly getting heavier... Now, after this patch, if you replace a heavy default delegate with a light and simple custom delegate, the result is a much faster control. For example, replacing Material style Button's background, which has a shadow effect, with a plain Rectangle gives a ~10x boost, because the default background with its heavy shadow effect is not executed at all. At the same time, deferring the execution of the default delegates avoids troubles with asynchronous incubation, because we don't need to destroy an object in the middle of the incubation process. Task-number: QTBUG-50992 Change-Id: I2274bff99b9ff126d3748278d58d859222910c98 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickabstractbutton.cpp | 30 +++- src/quicktemplates2/qquickabstractbutton_p.h | 3 + src/quicktemplates2/qquickabstractbutton_p_p.h | 6 +- src/quicktemplates2/qquickcontrol.cpp | 25 +++- src/quicktemplates2/qquickcontrol_p_p.h | 8 +- src/quicktemplates2/qquickdeferredexecute.cpp | 110 ++++++++++++++ src/quicktemplates2/qquickdeferredexecute_p_p.h | 79 ++++++++++ src/quicktemplates2/qquickdeferredpointer_p_p.h | 189 ++++++++++++++++++++++++ src/quicktemplates2/quicktemplates2.pri | 3 + 9 files changed, 442 insertions(+), 11 deletions(-) create mode 100644 src/quicktemplates2/qquickdeferredexecute.cpp create mode 100644 src/quicktemplates2/qquickdeferredexecute_p_p.h create mode 100644 src/quicktemplates2/qquickdeferredpointer_p_p.h (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index efd06bd0..f87ee0ef 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -37,6 +37,7 @@ #include "qquickabstractbutton_p.h" #include "qquickabstractbutton_p_p.h" #include "qquickbuttongroup_p.h" +#include "qquickdeferredexecute_p_p.h" #include #include @@ -130,6 +131,12 @@ QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() { } +QQuickItem *QQuickAbstractButtonPrivate::getContentItem() +{ + executeContentItem(); + return QQuickControlPrivate::getContentItem(); +} + void QQuickAbstractButtonPrivate::handlePress(const QPointF &point) { Q_Q(QQuickAbstractButton); @@ -258,6 +265,12 @@ void QQuickAbstractButtonPrivate::toggle(bool value) emit q->toggled(); } +void QQuickAbstractButtonPrivate::executeIndicator() +{ + Q_Q(QQuickAbstractButton); + quickExecuteDeferred(q, QStringLiteral("indicator"), indicator); +} + QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const { Q_Q(const QQuickAbstractButton); @@ -545,7 +558,8 @@ void QQuickAbstractButton::setAutoRepeat(bool repeat) */ QQuickItem *QQuickAbstractButton::indicator() const { - Q_D(const QQuickAbstractButton); + QQuickAbstractButtonPrivate *d = const_cast(d_func()); + d->executeIndicator(); return d->indicator; } @@ -555,14 +569,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(); } /*! @@ -576,6 +591,15 @@ void QQuickAbstractButton::toggle() setChecked(!d->checked); } +void QQuickAbstractButton::componentComplete() +{ + Q_D(QQuickAbstractButton); + d->executeIndicator(); + d->executeBackground(); + d->executeContentItem(); + QQuickControl::componentComplete(); +} + void QQuickAbstractButton::focusOutEvent(QFocusEvent *event) { Q_D(QQuickAbstractButton); diff --git a/src/quicktemplates2/qquickabstractbutton_p.h b/src/quicktemplates2/qquickabstractbutton_p.h index 71884bf6..a1210567 100644 --- a/src/quicktemplates2/qquickabstractbutton_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p.h @@ -64,6 +64,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAbstractButton : public QQuickContr Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged FINAL) Q_PROPERTY(bool autoExclusive READ autoExclusive WRITE setAutoExclusive NOTIFY autoExclusiveChanged FINAL) Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator") public: explicit QQuickAbstractButton(QQuickItem *parent = nullptr); @@ -117,6 +118,8 @@ Q_SIGNALS: protected: QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent); + void componentComplete() override; + void focusOutEvent(QFocusEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index 39af6896..5a2a52c7 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -67,6 +67,8 @@ public: return button->d_func(); } + QQuickItem *getContentItem() override; + void handlePress(const QPointF &point) override; void handleMove(const QPointF &point) override; void handleRelease(const QPointF &point) override; @@ -85,6 +87,8 @@ public: void toggle(bool value); + void executeIndicator(); + QString text; bool down; bool explicitDown; @@ -100,7 +104,7 @@ public: int repeatTimer; QPointF pressPoint; Qt::MouseButtons pressButtons; - QQuickItem *indicator; + QQuickDeferredPointer indicator; QQuickButtonGroup *group; }; diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 908c0f42..51248745 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 #include @@ -290,7 +291,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) return; q->contentItemChange(item, contentItem); - destroyDelegate(contentItem, q); + delete contentItem; contentItem = item; if (item) { @@ -300,7 +301,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) resizeContent(); } - if (notify) + if (notify && !contentItem.isExecuting()) emit q->contentItemChanged(); } @@ -933,6 +934,18 @@ QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item) return QLocale(); } +void QQuickControlPrivate::executeContentItem() +{ + Q_Q(QQuickControl); + quickExecuteDeferred(q, QStringLiteral("contentItem"), contentItem); +} + +void QQuickControlPrivate::executeBackground() +{ + Q_Q(QQuickControl); + quickExecuteDeferred(q, QStringLiteral("background"), background); +} + /* Cancels incubation recursively to avoid "Object destroyed during incubation" (QTBUG-50992) */ @@ -1214,7 +1227,8 @@ void QQuickControl::setWheelEnabled(bool enabled) */ QQuickItem *QQuickControl::background() const { - Q_D(const QQuickControl); + QQuickControlPrivate *d = const_cast(d_func()); + d->executeBackground(); return d->background; } @@ -1224,7 +1238,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); @@ -1233,7 +1247,8 @@ void QQuickControl::setBackground(QQuickItem *background) if (isComponentComplete()) d->resizeBackground(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 73e1b44c..84a42fa5 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -49,6 +49,7 @@ // #include "qquickcontrol_p.h" +#include "qquickdeferredpointer_p_p.h" #include #include @@ -126,6 +127,9 @@ public: static bool calcHoverEnabled(const QQuickItem *item); #endif + void executeContentItem(); + void executeBackground(); + static void destroyDelegate(QObject *object, QObject *parent); struct ExtraData { @@ -155,8 +159,8 @@ public: QLocale locale; Qt::FocusPolicy focusPolicy; Qt::FocusReason focusReason; - QQuickItem *background; - QQuickItem *contentItem; + QQuickDeferredPointer background; + QQuickDeferredPointer contentItem; QQuickAccessibleAttached *accessibleAttached; }; diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp new file mode 100644 index 00000000..7ec4e8e8 --- /dev/null +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace QtQuickPrivate { + +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 QV4PropertyBindingHash; + auto it = std::reverse_iterator(range.second); + auto last = std::reverse_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 executeDeferred(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; + beginDeferred(ep, QQmlProperty(object, property), &state); + + // Release deferred data for those compilation units that no longer have deferred bindings + data->releaseDeferredData(); + + QQmlComponentPrivate::completeDeferred(ep, &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..2157d7ef --- /dev/null +++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 +#include + +QT_BEGIN_NAMESPACE + +class QString; +class QObject; + +namespace QtQuickPrivate { + void executeDeferred(QObject *object, const QString &property); +} + +template +void quickExecuteDeferred(QObject *object, const QString &property, QQuickDeferredPointer &delegate) +{ + if (!delegate.isNull() || delegate.wasExecuted()) + return; + + delegate.setExecuting(true); + QtQuickPrivate::executeDeferred(object, property); + delegate.setExecuting(false); + + if (!delegate.isNull()) + 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 + +QT_BEGIN_NAMESPACE + +template +class QQuickDeferredPointer +{ +public: + inline QQuickDeferredPointer(); + inline QQuickDeferredPointer(T *); + inline QQuickDeferredPointer(const QQuickDeferredPointer &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 &operator=(T *); + inline QQuickDeferredPointer &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 +QQuickDeferredPointer::QQuickDeferredPointer() +: ptr_value(0) +{ +} + +template +QQuickDeferredPointer::QQuickDeferredPointer(T *v) +: ptr_value(quintptr(v)) +{ + Q_ASSERT((ptr_value & FlagsMask) == 0); +} + +template +QQuickDeferredPointer::QQuickDeferredPointer(const QQuickDeferredPointer &o) +: ptr_value(o.ptr_value) +{ +} + +template +bool QQuickDeferredPointer::isNull() const +{ + return 0 == (ptr_value & (~FlagsMask)); +} + +template +bool QQuickDeferredPointer::wasExecuted() const +{ + return ptr_value & WasExecutedBit; +} + +template +void QQuickDeferredPointer::setExecuted() +{ + ptr_value |= WasExecutedBit; +} + +template +bool QQuickDeferredPointer::isExecuting() const +{ + return ptr_value & IsExecutingBit; +} + +template +void QQuickDeferredPointer::setExecuting(bool b) +{ + if (b) + ptr_value |= IsExecutingBit; + else + ptr_value &= ~IsExecutingBit; +} + +template +QQuickDeferredPointer::operator T*() const +{ + return data(); +} + +template +QQuickDeferredPointer::operator bool() const +{ + return !isNull(); +} + +template +T *QQuickDeferredPointer::data() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template +T *QQuickDeferredPointer::operator*() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template +T *QQuickDeferredPointer::operator->() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template +QQuickDeferredPointer &QQuickDeferredPointer::operator=(T *o) +{ + Q_ASSERT((quintptr(o) & FlagsMask) == 0); + + ptr_value = quintptr(o) | (ptr_value & FlagsMask); + return *this; +} + +template +QQuickDeferredPointer &QQuickDeferredPointer::operator=(const QQuickDeferredPointer &o) +{ + ptr_value = o.ptr_value; + return *this; +} + +QT_END_NAMESPACE + +#endif // QQUICKDEFERREDPOINTER_P_P_H diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index a7570ec5..95039681 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -15,6 +15,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 \ @@ -91,6 +93,7 @@ SOURCES += \ $$PWD/qquickcombobox.cpp \ $$PWD/qquickcontainer.cpp \ $$PWD/qquickcontrol.cpp \ + $$PWD/qquickdeferredexecute.cpp \ $$PWD/qquickdelaybutton.cpp \ $$PWD/qquickdial.cpp \ $$PWD/qquickdialog.cpp \ -- cgit v1.2.3 From d9e740d2ccf8c1d3caacfcd95537718048e3a7ba Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 21:49:53 +0100 Subject: Migitate the performance regression caused by deferred execution 458eb65f7 introduced a performance regression. Before 458eb65f7, qmlbench delegates_button.qml results were around 40 frames on a TX1. After 458eb65f, it dropped to 32. This patch is unfortunately not able to bring it on the original level, but at least improves the results to 37. For QQuickText, it is extremely important that implicitWidth() gets called before the component is completed, to avoid doing implicit size calculation multiple times. Deferred execution caused a performance regression by creating contentItem in "one go". We need to split the deferred execution to two parts so that bindings get first setup, and later enabled upon completion. This way, we utilize QQuickText's performance optimization for implicit size calculation. Task-number: QTBUG-50992 Change-Id: I4bf00af71b6d7dbf1d4b58b00fe547c6c321f8ed Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickabstractbutton.cpp | 28 ++++++++++++++++-------- src/quicktemplates2/qquickabstractbutton_p_p.h | 2 +- src/quicktemplates2/qquickcontrol.cpp | 27 ++++++++++++++++++----- src/quicktemplates2/qquickcontrol_p_p.h | 4 ++-- src/quicktemplates2/qquickdeferredexecute.cpp | 29 +++++++++++++++++++++---- src/quicktemplates2/qquickdeferredexecute_p_p.h | 22 ++++++++++++------- 6 files changed, 83 insertions(+), 29 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index f87ee0ef..48d5fceb 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -133,8 +133,9 @@ QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() QQuickItem *QQuickAbstractButtonPrivate::getContentItem() { - executeContentItem(); - return QQuickControlPrivate::getContentItem(); + if (!contentItem) + executeContentItem(); + return contentItem; } void QQuickAbstractButtonPrivate::handlePress(const QPointF &point) @@ -265,10 +266,18 @@ void QQuickAbstractButtonPrivate::toggle(bool value) emit q->toggled(); } -void QQuickAbstractButtonPrivate::executeIndicator() +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickAbstractButtonPrivate::executeIndicator(bool complete) { - Q_Q(QQuickAbstractButton); - quickExecuteDeferred(q, QStringLiteral("indicator"), indicator); + Q_Q(QQuickControl); + if (indicator.wasExecuted()) + return; + + if (!indicator) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); } QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const @@ -559,7 +568,8 @@ void QQuickAbstractButton::setAutoRepeat(bool repeat) QQuickItem *QQuickAbstractButton::indicator() const { QQuickAbstractButtonPrivate *d = const_cast(d_func()); - d->executeIndicator(); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -594,9 +604,9 @@ void QQuickAbstractButton::toggle() void QQuickAbstractButton::componentComplete() { Q_D(QQuickAbstractButton); - d->executeIndicator(); - d->executeBackground(); - d->executeContentItem(); + d->executeIndicator(true); + d->executeBackground(true); + d->executeContentItem(true); QQuickControl::componentComplete(); } diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index 5a2a52c7..0d8eab81 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -87,7 +87,7 @@ public: void toggle(bool value); - void executeIndicator(); + void executeIndicator(bool complete = false); QString text; bool down; diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 51248745..2f3791d5 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -934,16 +934,32 @@ QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item) return QLocale(); } -void QQuickControlPrivate::executeContentItem() +static inline QString contentItemName() { return QStringLiteral("contentItem"); } + +void QQuickControlPrivate::executeContentItem(bool complete) { Q_Q(QQuickControl); - quickExecuteDeferred(q, QStringLiteral("contentItem"), contentItem); + if (contentItem.wasExecuted()) + return; + + if (!contentItem) + quickBeginDeferred(q, contentItemName(), contentItem); + if (complete) + quickCompleteDeferred(q, contentItemName(), contentItem); } -void QQuickControlPrivate::executeBackground() +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickControlPrivate::executeBackground(bool complete) { Q_Q(QQuickControl); - quickExecuteDeferred(q, QStringLiteral("background"), background); + if (background.wasExecuted()) + return; + + if (!background) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); } /* @@ -1228,7 +1244,8 @@ void QQuickControl::setWheelEnabled(bool enabled) QQuickItem *QQuickControl::background() const { QQuickControlPrivate *d = const_cast(d_func()); - d->executeBackground(); + if (!d->background) + d->executeBackground(); return d->background; } diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 84a42fa5..d8b1dd40 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -127,8 +127,8 @@ public: static bool calcHoverEnabled(const QQuickItem *item); #endif - void executeContentItem(); - void executeBackground(); + void executeContentItem(bool complete = false); + 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 7ec4e8e8..802ed3d0 100644 --- a/src/quicktemplates2/qquickdeferredexecute.cpp +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -36,6 +36,7 @@ #include "qquickdeferredexecute_p_p.h" +#include #include #include #include @@ -45,6 +46,15 @@ QT_BEGIN_NAMESPACE namespace QtQuickPrivate { +typedef QHash 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(); @@ -89,20 +99,31 @@ static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro } } -void executeDeferred(QObject *object, const QString &property) +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; - beginDeferred(ep, QQmlProperty(object, property), &state); + 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(); - QQmlComponentPrivate::completeDeferred(ep, &state); + 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 diff --git a/src/quicktemplates2/qquickdeferredexecute_p_p.h b/src/quicktemplates2/qquickdeferredexecute_p_p.h index 2157d7ef..87124e48 100644 --- a/src/quicktemplates2/qquickdeferredexecute_p_p.h +++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h @@ -57,21 +57,27 @@ class QString; class QObject; namespace QtQuickPrivate { - void executeDeferred(QObject *object, const QString &property); + void beginDeferred(QObject *object, const QString &property); + void completeDeferred(QObject *object, const QString &property); } template -void quickExecuteDeferred(QObject *object, const QString &property, QQuickDeferredPointer &delegate) +void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer &delegate) { - if (!delegate.isNull() || delegate.wasExecuted()) - return; - + Q_ASSERT(delegate.isNull()); delegate.setExecuting(true); - QtQuickPrivate::executeDeferred(object, property); + QtQuickPrivate::beginDeferred(object, property); delegate.setExecuting(false); +} - if (!delegate.isNull()) - delegate.setExecuted(); +template +void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer &delegate) +{ + Q_ASSERT(!delegate.wasExecuted()); + delegate.setExecuting(true); + QtQuickPrivate::completeDeferred(object, property); + delegate.setExecuting(false); + delegate.setExecuted(); } QT_END_NAMESPACE -- cgit v1.2.3 From f38d6c5bd2eba72d68018f39581263d8b43de238 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 14:30:12 +0100 Subject: Slider: use deferred execution Note: It is important to repeat the names of the deferred properties in base classes. The QML engine ask for the class info from the meta- object. A class info declaration in a sub-class overshadows the class info declaration by the same name in the base class. Task-number: QTBUG-50992 Change-Id: Ib674b943db2f0bf196c9386ea22b511715c0a98f Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickslider.cpp | 30 ++++++++++++++++++++++++++---- src/quicktemplates2/qquickslider_p.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index da2f402f..d4cbf61c 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 @@ -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 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) { @@ -485,7 +502,9 @@ void QQuickSlider::setOrientation(Qt::Orientation orientation) */ QQuickItem *QQuickSlider::handle() const { - Q_D(const QQuickSlider); + QQuickSliderPrivate *d = const_cast(d_func()); + if (!d->handle) + d->executeHandle(); return d->handle; } @@ -495,11 +514,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(); } /*! @@ -704,6 +724,8 @@ void QQuickSlider::mirrorChange() void QQuickSlider::componentComplete() { Q_D(QQuickSlider); + d->executeHandle(true); + d->executeBackground(true); QQuickControl::componentComplete(); setValue(d->value); d->updatePosition(); diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h index f33c330a..377e853a 100644 --- a/src/quicktemplates2/qquickslider_p.h +++ b/src/quicktemplates2/qquickslider_p.h @@ -68,6 +68,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2) + Q_CLASSINFO("DeferredPropertyNames", "background,handle") public: explicit QQuickSlider(QQuickItem *parent = nullptr); -- cgit v1.2.3 From 417b8459c3311fbf397fe82b9e76580469ec8ce8 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 14:40:17 +0100 Subject: Dial: use deferred execution Task-number: QTBUG-50992 Change-Id: I432be00d81344ce129bc8906370555b134fdf423 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickdial.cpp | 30 ++++++++++++++++++++++++++---- src/quicktemplates2/qquickdial_p.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index c0e2c8ed..46085c47 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 #include @@ -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 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(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,8 @@ void QQuickDial::mirrorChange() void QQuickDial::componentComplete() { Q_D(QQuickDial); + d->executeHandle(true); + d->executeBackground(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); -- cgit v1.2.3 From 83b093f172435f7347d7a22d8265a761f450a203 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 14:54:12 +0100 Subject: Label: use deferred execution Task-number: QTBUG-50992 Change-Id: I8e626d1a0585f93cbd612aca39a1e9050f5e0ed3 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquicklabel.cpp | 25 ++++++++++++++++++++++--- src/quicktemplates2/qquicklabel_p.h | 1 + src/quicktemplates2/qquicklabel_p_p.h | 5 ++++- 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index d1ddfbd6..418a7834 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 #include @@ -155,6 +156,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) { @@ -190,7 +205,9 @@ void QQuickLabel::setFont(const QFont &font) */ QQuickItem *QQuickLabel::background() const { - Q_D(const QQuickLabel); + QQuickLabelPrivate *d = const_cast(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -200,14 +217,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(); } void QQuickLabel::classBegin() @@ -220,6 +238,7 @@ void QQuickLabel::classBegin() void QQuickLabel::componentComplete() { Q_D(QQuickLabel); + d->executeBackground(true); QQuickText::componentComplete(); #if QT_CONFIG(accessibility) if (!d->accessibleAttached && QAccessible::isActive()) diff --git a/src/quicktemplates2/qquicklabel_p.h b/src/quicktemplates2/qquicklabel_p.h index 04172900..c31e173b 100644 --- a/src/quicktemplates2/qquicklabel_p.h +++ b/src/quicktemplates2/qquicklabel_p.h @@ -60,6 +60,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickLabel : public QQuickText Q_OBJECT Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) // override Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + 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 c24c855b..b8ad2ae7 100644 --- a/src/quicktemplates2/qquicklabel_p_p.h +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -49,6 +49,7 @@ // #include +#include #if QT_CONFIG(accessibility) #include @@ -84,8 +85,10 @@ public: QAccessible::Role accessibleRole() const override; #endif + void executeBackground(bool complete = false); + QFont font; - QQuickItem *background; + QQuickDeferredPointer background; QQuickAccessibleAttached *accessibleAttached; }; -- cgit v1.2.3 From 0195d0b1b4a2d17aeb2dfd09e6ab62d953c5cdce Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 15:20:55 +0100 Subject: TextField: use deferred execution Task-number: QTBUG-50992 Change-Id: I99a8d97e7f25cfff398fb30e365c7b245b738c37 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquicktextfield.cpp | 25 ++++++++++++++++++++++--- src/quicktemplates2/qquicktextfield_p.h | 1 + src/quicktemplates2/qquicktextfield_p_p.h | 5 ++++- 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 397e666e..2d432ec0 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 #include @@ -265,6 +266,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) { @@ -306,7 +321,9 @@ void QQuickTextField::setFont(const QFont &font) */ QQuickItem *QQuickTextField::background() const { - Q_D(const QQuickTextField); + QQuickTextFieldPrivate *d = const_cast(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -316,7 +333,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); @@ -325,7 +342,8 @@ void QQuickTextField::setBackground(QQuickItem *background) if (isComponentComplete()) d->resizeBackground(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -461,6 +479,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 49e0be13..eb84fe62 100644 --- a/src/quicktemplates2/qquicktextfield_p.h +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -69,6 +69,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput // 2.1 (Qt 5.8) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION 1) Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) + 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 31ccb361..037c6a21 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -50,6 +50,7 @@ #include #include +#include #include "qquicktextfield_p.h" @@ -97,12 +98,14 @@ public: QAccessible::Role accessibleRole() const override; #endif + void executeBackground(bool complete = false); + #if QT_CONFIG(quicktemplates2_hover) bool hovered; bool explicitHoverEnabled; #endif QFont font; - QQuickItem *background; + QQuickDeferredPointer background; QString placeholder; Qt::FocusReason focusReason; QQuickPressHandler pressHandler; -- cgit v1.2.3 From 2567cb8e405b72a50cdba0cffd98aa2f4ede3c54 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 15:31:55 +0100 Subject: TextArea: use deferred execution Task-number: QTBUG-50992 Change-Id: I6d205f8ea0c90986b18b7e6cedbf347f1ce38eec Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquicktextarea.cpp | 25 ++++++++++++++++++++++--- src/quicktemplates2/qquicktextarea_p.h | 1 + src/quicktemplates2/qquicktextarea_p_p.h | 5 ++++- 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 8c48bdf9..06867742 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 #include @@ -391,6 +392,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) { @@ -444,7 +459,9 @@ void QQuickTextArea::setFont(const QFont &font) */ QQuickItem *QQuickTextArea::background() const { - Q_D(const QQuickTextArea); + QQuickTextAreaPrivate *d = const_cast(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -454,7 +471,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); @@ -463,7 +480,8 @@ void QQuickTextArea::setBackground(QQuickItem *background) if (isComponentComplete()) d->resizeBackground(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -607,6 +625,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 507f8b14..86d91346 100644 --- a/src/quicktemplates2/qquicktextarea_p.h +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -70,6 +70,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit // 2.1 (Qt 5.8) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION 1) Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) + 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 ef2c7237..ede9d97f 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -51,6 +51,7 @@ #include #include #include +#include #include "qquicktextarea_p.h" @@ -108,12 +109,14 @@ public: QAccessible::Role accessibleRole() const override; #endif + void executeBackground(bool complete = false); + #if QT_CONFIG(quicktemplates2_hover) bool hovered; bool explicitHoverEnabled; #endif QFont font; - QQuickItem *background; + QQuickDeferredPointer background; QString placeholder; Qt::FocusReason focusReason; QQuickPressHandler pressHandler; -- cgit v1.2.3 From 59f72376602c306f6322c9482e2201f1cc9e3819 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 11 Dec 2017 16:02:40 +0100 Subject: RangeSlider: use deferred execution Task-number: QTBUG-50992 Change-Id: Ibbc946c3402c65f9b100fc74dde04e4d439c8535 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickrangeslider.cpp | 47 +++++++++++++++++++++++++++---- src/quicktemplates2/qquickrangeslider_p.h | 3 ++ 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 274c887d..44c00f68 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 #include @@ -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 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(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 @@ -1045,13 +1065,28 @@ 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); + d->executeBackground(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 fc5a1d99..cc071974 100644 --- a/src/quicktemplates2/qquickrangeslider_p.h +++ b/src/quicktemplates2/qquickrangeslider_p.h @@ -67,6 +67,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSlider : public QQuickControl Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) // 2.2 (Qt 5.9) Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2) + Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickRangeSlider(QQuickItem *parent = nullptr); @@ -124,6 +125,7 @@ protected: void touchEvent(QTouchEvent *event) override; #endif void mirrorChange() override; + void classBegin() override; void componentComplete() override; #if QT_CONFIG(accessibility) @@ -149,6 +151,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); -- cgit v1.2.3 From 1c265b23ef7494abc6a00094e781a8e48de87121 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 13 Dec 2017 17:03:37 +0100 Subject: ApplicationWindow: use deferred execution Task-number: QTBUG-50992 Change-Id: Ia07055d2fa3d30c91bdf3c526cf7301c7ed1ce2b Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickapplicationwindow.cpp | 30 +++++++++++++++++++++---- src/quicktemplates2/qquickapplicationwindow_p.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index e3f16d55..c1a7f301 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 #include @@ -173,8 +175,10 @@ public: static void contentData_append(QQmlListProperty *prop, QObject *obj); + void executeBackground(bool complete = false); + bool complete; - QQuickItem *background; + QQuickDeferredPointer background; QQuickItem *contentItem; QQuickItem *header; QQuickItem *footer; @@ -295,6 +299,20 @@ void QQuickApplicationWindowPrivate::contentData_append(QQmlListPropertysetWindow(static_cast(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) { @@ -336,7 +354,9 @@ QQuickApplicationWindow::~QQuickApplicationWindow() */ QQuickItem *QQuickApplicationWindow::background() const { - Q_D(const QQuickApplicationWindow); + QQuickApplicationWindowPrivate *d = const_cast(d_func()); + if (!d->background) + d->executeBackground(); return d->background; } @@ -346,7 +366,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()); @@ -355,7 +375,8 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background) if (isComponentComplete()) d->relayout(); } - emit backgroundChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); } /*! @@ -716,6 +737,7 @@ void QQuickApplicationWindow::componentComplete() { Q_D(QQuickApplicationWindow); d->complete = true; + d->executeBackground(true); QQuickWindowQmlImpl::componentComplete(); } diff --git a/src/quicktemplates2/qquickapplicationwindow_p.h b/src/quicktemplates2/qquickapplicationwindow_p.h index 07ddc67e..c1e7935b 100644 --- a/src/quicktemplates2/qquickapplicationwindow_p.h +++ b/src/quicktemplates2/qquickapplicationwindow_p.h @@ -72,6 +72,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindow : public QQuickWi Q_PROPERTY(QQuickOverlay *overlay READ overlay CONSTANT FINAL) Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged FINAL) Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) + Q_CLASSINFO("DeferredPropertyNames", "background") Q_CLASSINFO("DefaultProperty", "contentData") public: -- cgit v1.2.3 From 3ec6d04d976249d162f6ec92666d9008f4c21c34 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 13 Dec 2017 13:35:52 +0100 Subject: ComboBox: use deferred execution As a special case, ComboBox defers the execution of the popup until the popup is either accessed or made visible. This gives a nice boost in creation time benchmarks (20->25, ~25%). The old optimization of setting the delegate model only when the popup is visible is no longer needed. Task-number: QTBUG-50992 Change-Id: Ifeaceb759ab676bb54c6bc09dc97810eade72ca1 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcombobox.cpp | 106 +++++++++++++++++++++++++-------- src/quicktemplates2/qquickcombobox_p.h | 1 + 2 files changed, 81 insertions(+), 26 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index d22e09d5..dde27e2a 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -38,6 +38,7 @@ #include "qquickcontrol_p_p.h" #include "qquickabstractbutton_p.h" #include "qquickpopup_p_p.h" +#include "qquickdeferredexecute_p_p.h" #include #include @@ -252,6 +253,11 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + QQuickItem *getContentItem() override; + + void executeIndicator(bool complete = false); + void executePopup(bool complete = false); + bool flat; bool down; bool hasDown; @@ -268,8 +274,8 @@ public: QQuickItem *pressedItem; QQmlInstanceModel *delegateModel; QQmlComponent *delegate; - QQuickItem *indicator; - QQuickPopup *popup; + QQuickDeferredPointer indicator; + QQuickDeferredPointer popup; struct ExtraData { ExtraData() @@ -313,6 +319,9 @@ bool QQuickComboBoxPrivate::isPopupVisible() const void QQuickComboBoxPrivate::showPopup() { + if (!popup) + executePopup(true); + if (popup && !popup->isVisible()) popup->open(); } @@ -330,13 +339,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() @@ -366,8 +372,11 @@ void QQuickComboBoxPrivate::createdItem(int index, QObject *object) { Q_Q(QQuickComboBox); QQuickItem *item = qobject_cast(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); } @@ -662,6 +671,41 @@ void QQuickComboBoxPrivate::handleUngrab() q->setPressed(false); } +QQuickItem *QQuickComboBoxPrivate::getContentItem() +{ + if (!contentItem) + executeContentItem(); + return contentItem; +} + +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) { @@ -677,14 +721,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; + } } /*! @@ -969,7 +1012,9 @@ void QQuickComboBox::setDelegate(QQmlComponent* delegate) */ QQuickItem *QQuickComboBox::indicator() const { - Q_D(const QQuickComboBox); + QQuickComboBoxPrivate *d = const_cast(d_func()); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -979,13 +1024,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(); } /*! @@ -1003,7 +1049,9 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) */ QQuickPopup *QQuickComboBox::popup() const { - Q_D(const QQuickComboBox); + QQuickComboBoxPrivate *d = const_cast(d_func()); + if (!d->popup) + d->executePopup(isComponentComplete()); return d->popup; } @@ -1014,8 +1062,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; @@ -1023,7 +1071,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup) QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); } d->popup = popup; - emit popupChanged(); + if (!d->popup.isExecuting()) + emit popupChanged(); } /*! @@ -1494,7 +1543,7 @@ void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) { Q_D(QQuickComboBox); QQuickControl::keyReleaseEvent(event); - if (!d->popup || event->isAutoRepeat()) + if (event->isAutoRepeat()) return; switch (event->key()) { @@ -1541,6 +1590,11 @@ void QQuickComboBox::wheelEvent(QWheelEvent *event) void QQuickComboBox::componentComplete() { Q_D(QQuickComboBox); + d->executeIndicator(true); + d->executeBackground(true); + d->executeContentItem(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 030d068b..7c27ca99 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); -- cgit v1.2.3 From af0abc24e3e07917177f1a72af559db7eb15d9f4 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 13 Dec 2017 17:34:52 +0100 Subject: Pane: use deferred execution Task-number: QTBUG-50992 Change-Id: Ibba0e79f8eaf76336dad3708606484a2846b2912 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickpane.cpp | 10 ++++++++++ src/quicktemplates2/qquickpane_p.h | 3 +++ 2 files changed, 13 insertions(+) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index b89131c4..2425b865 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -113,6 +113,8 @@ QQuickPanePrivate::QQuickPanePrivate() QQuickItem *QQuickPanePrivate::getContentItem() { Q_Q(QQuickPane); + if (!contentItem) + executeContentItem(); if (!contentItem) return new QQuickItem(q); return contentItem; @@ -235,6 +237,14 @@ QQmlListProperty QQuickPane::contentChildren() QQuickItemPrivate::children_clear); } +void QQuickPane::componentComplete() +{ + Q_D(QQuickPane); + d->executeBackground(true); + d->executeContentItem(true); + QQuickControl::componentComplete(); +} + void QQuickPane::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) { QQuickControl::contentItemChange(newItem, oldItem); diff --git a/src/quicktemplates2/qquickpane_p.h b/src/quicktemplates2/qquickpane_p.h index 759c59d8..651a8589 100644 --- a/src/quicktemplates2/qquickpane_p.h +++ b/src/quicktemplates2/qquickpane_p.h @@ -62,6 +62,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPane : public QQuickControl Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL) Q_PROPERTY(QQmlListProperty contentData READ contentData FINAL) Q_PROPERTY(QQmlListProperty contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") Q_CLASSINFO("DefaultProperty", "contentData") public: @@ -84,6 +85,8 @@ Q_SIGNALS: protected: QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent); + void componentComplete() override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; #if QT_CONFIG(accessibility) -- cgit v1.2.3 From 4206f54c5080c0e45aabd42d6c6590b04b84b6a1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 14 Dec 2017 11:33:54 +0100 Subject: GroupBox: use deferred execution Task-number: QTBUG-50992 Change-Id: I3e5c8bf7cc39fae0e882440079bb43292ace1810 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickgroupbox.cpp | 37 ++++++++++++++++++++++++++++++---- src/quicktemplates2/qquickgroupbox_p.h | 3 +++ 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index 09bd49f6..674f5b18 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 @@ -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 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(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 e35db1fc..0468462e 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; #if QT_CONFIG(accessibility) -- cgit v1.2.3 From a60a28f8225709bfca338416630a0493853264e1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 13 Dec 2017 16:10:51 +0100 Subject: SpinBox: use deferred execution tst_controls::SpinBox::test_initialFocus() caught an issue that focus was not transferred as expected when the creation of the content item was deferred. Task-number: QTBUG-50992 Change-Id: I6b9f5684ab7141fa4ebfe4c7fe3e32528553b96d Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquickspinbox.cpp | 85 ++++++++++++++++++++++++++++------- src/quicktemplates2/qquickspinbox_p.h | 3 ++ 2 files changed, 73 insertions(+), 15 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 1989d768..d390f570 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 #include @@ -144,6 +145,8 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + QQuickItem *getContentItem() override; + bool editable; int from; int to; @@ -159,6 +162,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 indicator; +}; + int QQuickSpinBoxPrivate::boundValue(int value) const { return from > to ? qBound(to, value, from) : qBound(from, value, to); @@ -347,6 +374,13 @@ void QQuickSpinBoxPrivate::handleUngrab() stopPressRepeat(); } +QQuickItem *QQuickSpinBoxPrivate::getContentItem() +{ + if (!contentItem) + executeContentItem(); + return contentItem; +} + QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) : QQuickControl(*(new QQuickSpinBoxPrivate), parent) { @@ -833,9 +867,26 @@ 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); + d->executeBackground(true); + d->executeContentItem(true); + QQuickControl::componentComplete(); if (!d->setValue(d->value, false)) { d->updateUpEnabled(); @@ -859,6 +910,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); @@ -890,20 +943,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) @@ -928,7 +980,9 @@ void QQuickSpinButton::setPressed(bool pressed) QQuickItem *QQuickSpinButton::indicator() const { - Q_D(const QQuickSpinButton); + QQuickSpinButtonPrivate *d = const_cast(d_func()); + if (!d->indicator) + d->executeIndicator(); return d->indicator; } @@ -938,14 +992,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(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 e62f8614..7bb23e05 100644 --- a/src/quicktemplates2/qquickspinbox_p.h +++ b/src/quicktemplates2/qquickspinbox_p.h @@ -74,6 +74,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinBox : public QQuickControl // 2.2 (Qt 5.9) 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_CLASSINFO("DeferredPropertyNames", "background,contentItem") public: explicit QQuickSpinBox(QQuickItem *parent = nullptr); @@ -141,6 +142,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; @@ -164,6 +166,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); -- cgit v1.2.3 From 4a077f719dff799a89b5f370dfc71a7bd14b0930 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 14 Dec 2017 15:41:11 +0100 Subject: Page: use deferred execution Change-Id: Icb22f656893c89f61233bb547f03e63240bb8f97 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickpage.cpp | 4 ++++ src/quicktemplates2/qquickpage_p.h | 1 + 2 files changed, 5 insertions(+) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 50050df3..f679d90a 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -106,6 +106,8 @@ QQuickPagePrivate::QQuickPagePrivate() QQuickItem *QQuickPagePrivate::getContentItem() { Q_Q(QQuickPage); + if (!contentItem) + executeContentItem(); if (!contentItem) return new QQuickItem(q); return contentItem; @@ -330,6 +332,8 @@ void QQuickPage::setContentHeight(qreal height) void QQuickPage::componentComplete() { Q_D(QQuickPage); + d->executeBackground(true); + d->executeContentItem(true); QQuickControl::componentComplete(); d->layout->update(); } diff --git a/src/quicktemplates2/qquickpage_p.h b/src/quicktemplates2/qquickpage_p.h index 0789e996..a2161ab5 100644 --- a/src/quicktemplates2/qquickpage_p.h +++ b/src/quicktemplates2/qquickpage_p.h @@ -66,6 +66,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPage : public QQuickControl // 2.1 (Qt 5.8) Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL REVISION 1) Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL REVISION 1) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") Q_CLASSINFO("DefaultProperty", "contentData") public: -- cgit v1.2.3 From a03f18e026bb564237702cab477589b6916a0102 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 14 Dec 2017 15:50:32 +0100 Subject: Control: defer the execution of the background item Task-number: QTBUG-50992 Change-Id: I6372e143c68f0a5bf7212d759281acef3c81618e Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickabstractbutton.cpp | 1 - src/quicktemplates2/qquickcombobox.cpp | 1 - src/quicktemplates2/qquickcontrol.cpp | 1 + src/quicktemplates2/qquickcontrol_p.h | 1 + src/quicktemplates2/qquickdial.cpp | 1 - src/quicktemplates2/qquickpage.cpp | 1 - src/quicktemplates2/qquickpane.cpp | 1 - src/quicktemplates2/qquickrangeslider.cpp | 1 - src/quicktemplates2/qquickrangeslider_p.h | 1 - src/quicktemplates2/qquickslider.cpp | 1 - src/quicktemplates2/qquickspinbox.cpp | 1 - 11 files changed, 2 insertions(+), 9 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 48d5fceb..7448ac9a 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -605,7 +605,6 @@ void QQuickAbstractButton::componentComplete() { Q_D(QQuickAbstractButton); d->executeIndicator(true); - d->executeBackground(true); d->executeContentItem(true); QQuickControl::componentComplete(); } diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index dde27e2a..357800d6 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -1591,7 +1591,6 @@ void QQuickComboBox::componentComplete() { Q_D(QQuickComboBox); d->executeIndicator(true); - d->executeBackground(true); d->executeContentItem(true); if (d->popup) d->executePopup(true); diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 2f3791d5..26f1f7e8 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -1320,6 +1320,7 @@ void QQuickControl::classBegin() void QQuickControl::componentComplete() { Q_D(QQuickControl); + d->executeBackground(true); QQuickItem::componentComplete(); d->resizeContent(); if (!d->hasLocale) diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 8b52bd02..4cc4a205 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -78,6 +78,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) + Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickControl(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index 46085c47..964cefe1 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -751,7 +751,6 @@ void QQuickDial::componentComplete() { Q_D(QQuickDial); d->executeHandle(true); - d->executeBackground(true); QQuickControl::componentComplete(); setValue(d->value); d->updatePosition(); diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index f679d90a..98ce75e9 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -332,7 +332,6 @@ void QQuickPage::setContentHeight(qreal height) void QQuickPage::componentComplete() { Q_D(QQuickPage); - d->executeBackground(true); d->executeContentItem(true); QQuickControl::componentComplete(); d->layout->update(); diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index 2425b865..b1175302 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -240,7 +240,6 @@ QQmlListProperty QQuickPane::contentChildren() void QQuickPane::componentComplete() { Q_D(QQuickPane); - d->executeBackground(true); d->executeContentItem(true); QQuickControl::componentComplete(); } diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 44c00f68..51b646ce 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -1084,7 +1084,6 @@ void QQuickRangeSlider::componentComplete() QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second); firstPrivate->executeHandle(true); secondPrivate->executeHandle(true); - d->executeBackground(true); QQuickControl::componentComplete(); diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h index cc071974..b8182768 100644 --- a/src/quicktemplates2/qquickrangeslider_p.h +++ b/src/quicktemplates2/qquickrangeslider_p.h @@ -67,7 +67,6 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSlider : public QQuickControl Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) // 2.2 (Qt 5.9) Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2) - Q_CLASSINFO("DeferredPropertyNames", "background") public: explicit QQuickRangeSlider(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index d4cbf61c..73fa2725 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -725,7 +725,6 @@ void QQuickSlider::componentComplete() { Q_D(QQuickSlider); d->executeHandle(true); - d->executeBackground(true); QQuickControl::componentComplete(); setValue(d->value); d->updatePosition(); diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index d390f570..1f821ac6 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -884,7 +884,6 @@ void QQuickSpinBox::componentComplete() Q_D(QQuickSpinBox); QQuickSpinButtonPrivate::get(d->up)->executeIndicator(true); QQuickSpinButtonPrivate::get(d->down)->executeIndicator(true); - d->executeBackground(true); d->executeContentItem(true); QQuickControl::componentComplete(); -- cgit v1.2.3 From 6b89293b99e763589181fd1f75470712f52cee3c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 14 Dec 2017 20:00:46 +0100 Subject: Control: defer the execution of the content item Tumbler is excluded because test_customContentItemAtConstruction() starts failing if deferred execution is enabled for the content item. Task-number: QTBUG-50992 Change-Id: I11022c3c380311396453cf6229e068e4aae2d82a Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickabstractbutton.cpp | 8 -------- src/quicktemplates2/qquickabstractbutton_p_p.h | 2 -- src/quicktemplates2/qquickcombobox.cpp | 10 ---------- src/quicktemplates2/qquickcontainer.cpp | 2 ++ src/quicktemplates2/qquickcontrol.cpp | 3 +++ src/quicktemplates2/qquickcontrol_p.h | 2 +- src/quicktemplates2/qquickpage.cpp | 9 +++------ src/quicktemplates2/qquickpage_p.h | 1 - src/quicktemplates2/qquickpane.cpp | 15 +++------------ src/quicktemplates2/qquickpane_p.h | 3 --- src/quicktemplates2/qquickpopupitem.cpp | 6 +++--- src/quicktemplates2/qquickscrollview.cpp | 2 ++ src/quicktemplates2/qquickspinbox.cpp | 10 ---------- src/quicktemplates2/qquickspinbox_p.h | 1 - src/quicktemplates2/qquicktumbler_p.h | 1 + 15 files changed, 18 insertions(+), 57 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 7448ac9a..45ade7bb 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -131,13 +131,6 @@ QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() { } -QQuickItem *QQuickAbstractButtonPrivate::getContentItem() -{ - if (!contentItem) - executeContentItem(); - return contentItem; -} - void QQuickAbstractButtonPrivate::handlePress(const QPointF &point) { Q_Q(QQuickAbstractButton); @@ -605,7 +598,6 @@ void QQuickAbstractButton::componentComplete() { Q_D(QQuickAbstractButton); d->executeIndicator(true); - d->executeContentItem(true); QQuickControl::componentComplete(); } diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index 0d8eab81..6634971e 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -67,8 +67,6 @@ public: return button->d_func(); } - QQuickItem *getContentItem() override; - void handlePress(const QPointF &point) override; void handleMove(const QPointF &point) override; void handleRelease(const QPointF &point) override; diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 357800d6..d221b9bc 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -253,8 +253,6 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; - QQuickItem *getContentItem() override; - void executeIndicator(bool complete = false); void executePopup(bool complete = false); @@ -671,13 +669,6 @@ void QQuickComboBoxPrivate::handleUngrab() q->setPressed(false); } -QQuickItem *QQuickComboBoxPrivate::getContentItem() -{ - if (!contentItem) - executeContentItem(); - return contentItem; -} - static inline QString indicatorName() { return QStringLiteral("indicator"); } void QQuickComboBoxPrivate::executeIndicator(bool complete) @@ -1591,7 +1582,6 @@ void QQuickComboBox::componentComplete() { Q_D(QQuickComboBox); d->executeIndicator(true); - d->executeContentItem(true); if (d->popup) d->executePopup(true); QQuickControl::componentComplete(); diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp index 7cf73841..ffed86b7 100644 --- a/src/quicktemplates2/qquickcontainer.cpp +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -578,6 +578,8 @@ QVariant QQuickContainer::contentModel() const QQmlListProperty QQuickContainer::contentData() { Q_D(QQuickContainer); + if (!d->contentItem) + d->executeContentItem(); return QQmlListProperty(this, d, QQuickContainerPrivate::contentData_append, QQuickContainerPrivate::contentData_count, diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 26f1f7e8..cfecc67c 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -281,6 +281,8 @@ void QQuickControlPrivate::resizeContent() QQuickItem *QQuickControlPrivate::getContentItem() { + if (!contentItem) + executeContentItem(); return contentItem; } @@ -1321,6 +1323,7 @@ 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 4cc4a205..6ccc5b71 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -78,7 +78,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) - Q_CLASSINFO("DeferredPropertyNames", "background") + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") public: explicit QQuickControl(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 98ce75e9..907b01e9 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -106,11 +106,9 @@ QQuickPagePrivate::QQuickPagePrivate() QQuickItem *QQuickPagePrivate::getContentItem() { Q_Q(QQuickPage); - if (!contentItem) - executeContentItem(); - if (!contentItem) - return new QQuickItem(q); - return contentItem; + if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + return item; + return new QQuickItem(q); } QQuickPage::QQuickPage(QQuickItem *parent) @@ -332,7 +330,6 @@ void QQuickPage::setContentHeight(qreal height) void QQuickPage::componentComplete() { Q_D(QQuickPage); - d->executeContentItem(true); QQuickControl::componentComplete(); d->layout->update(); } diff --git a/src/quicktemplates2/qquickpage_p.h b/src/quicktemplates2/qquickpage_p.h index a2161ab5..0789e996 100644 --- a/src/quicktemplates2/qquickpage_p.h +++ b/src/quicktemplates2/qquickpage_p.h @@ -66,7 +66,6 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPage : public QQuickControl // 2.1 (Qt 5.8) Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL REVISION 1) Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL REVISION 1) - Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") Q_CLASSINFO("DefaultProperty", "contentData") public: diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index b1175302..4c3e1422 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -113,11 +113,9 @@ QQuickPanePrivate::QQuickPanePrivate() QQuickItem *QQuickPanePrivate::getContentItem() { Q_Q(QQuickPane); - if (!contentItem) - executeContentItem(); - if (!contentItem) - return new QQuickItem(q); - return contentItem; + if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + return item; + return new QQuickItem(q); } QQuickPane::QQuickPane(QQuickItem *parent) @@ -237,13 +235,6 @@ QQmlListProperty QQuickPane::contentChildren() QQuickItemPrivate::children_clear); } -void QQuickPane::componentComplete() -{ - Q_D(QQuickPane); - d->executeContentItem(true); - QQuickControl::componentComplete(); -} - void QQuickPane::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) { QQuickControl::contentItemChange(newItem, oldItem); diff --git a/src/quicktemplates2/qquickpane_p.h b/src/quicktemplates2/qquickpane_p.h index 651a8589..759c59d8 100644 --- a/src/quicktemplates2/qquickpane_p.h +++ b/src/quicktemplates2/qquickpane_p.h @@ -62,7 +62,6 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPane : public QQuickControl Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL) Q_PROPERTY(QQmlListProperty contentData READ contentData FINAL) Q_PROPERTY(QQmlListProperty contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) - Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") Q_CLASSINFO("DefaultProperty", "contentData") public: @@ -85,8 +84,6 @@ Q_SIGNALS: protected: QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent); - void componentComplete() override; - void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index 6f9d7697..bd667835 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -95,9 +95,9 @@ void QQuickPopupItemPrivate::resolveFont() 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/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/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 1f821ac6..80bef2db 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -145,8 +145,6 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; - QQuickItem *getContentItem() override; - bool editable; int from; int to; @@ -374,13 +372,6 @@ void QQuickSpinBoxPrivate::handleUngrab() stopPressRepeat(); } -QQuickItem *QQuickSpinBoxPrivate::getContentItem() -{ - if (!contentItem) - executeContentItem(); - return contentItem; -} - QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) : QQuickControl(*(new QQuickSpinBoxPrivate), parent) { @@ -884,7 +875,6 @@ void QQuickSpinBox::componentComplete() Q_D(QQuickSpinBox); QQuickSpinButtonPrivate::get(d->up)->executeIndicator(true); QQuickSpinButtonPrivate::get(d->down)->executeIndicator(true); - d->executeContentItem(true); QQuickControl::componentComplete(); if (!d->setValue(d->value, false)) { diff --git a/src/quicktemplates2/qquickspinbox_p.h b/src/quicktemplates2/qquickspinbox_p.h index 7bb23e05..1ba21386 100644 --- a/src/quicktemplates2/qquickspinbox_p.h +++ b/src/quicktemplates2/qquickspinbox_p.h @@ -74,7 +74,6 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinBox : public QQuickControl // 2.2 (Qt 5.9) 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_CLASSINFO("DeferredPropertyNames", "background,contentItem") public: explicit QQuickSpinBox(QQuickItem *parent = nullptr); diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h index de7de595..480ebb23 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); -- cgit v1.2.3