aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-06-19 13:05:12 +0200
committerLiang Qi <liang.qi@qt.io>2019-06-19 13:05:12 +0200
commita2d36c9ef566a3e0ec42e297a3d314f134c87da1 (patch)
tree3cf02240bc190e0ae52c5cb1163e523635e443ab
parent15b90204fa5126f339db551cf7429534f1359322 (diff)
parente9520ec84c95e10a6826b2289e46552a2d446895 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: .qmake.conf src/imports/sharedimage/qsharedimageloader.cpp src/quick/items/qquickitemviewfxitem_p_p.h Change-Id: I12ce7c32788f4a394188a934e689b4ebac78138b
-rw-r--r--dist/changes-5.12.490
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp4
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h3
-rw-r--r--src/qml/animations/qanimationjobutil_p.h32
-rw-r--r--src/quick/items/qquickflickable.cpp2
-rw-r--r--src/quick/items/qquickitemview.cpp5
-rw-r--r--src/quick/items/qquickitemviewfxitem.cpp2
-rw-r--r--src/quick/items/qquickitemviewfxitem_p_p.h2
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp20
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp7
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h3
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp3
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode_p.h1
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp7
-rw-r--r--src/quick/util/qquicktransitionmanager_p_p.h2
-rw-r--r--src/quickshapes/qquickshape.cpp9
-rw-r--r--tests/auto/quick/qquickanimations/data/animationJobSelfDestructionBug.qml108
-rw-r--r--tests/auto/quick/qquickanimations/qquickanimations.pro1
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp21
22 files changed, 292 insertions, 38 deletions
diff --git a/dist/changes-5.12.4 b/dist/changes-5.12.4
new file mode 100644
index 0000000000..d963e44e67
--- /dev/null
+++ b/dist/changes-5.12.4
@@ -0,0 +1,90 @@
+Qt 5.12.4 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.12.0 through 5.12.3.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Important Behavior Changes *
+****************************************************************************
+
+ - [QTBUG-14769] TextEdit now uses the I-beam cursor by default, and the
+ pointing hand cursor for links. However in C++ it's still possible to
+ override with a custom cursor.
+ - [QTBUG-70826] The QML Runtime tool now has an updated application icon
+ and a default window icon. QtQuick applications can still use
+ QWindow::setIcon() to override the window icon.
+
+****************************************************************************
+* QtQml *
+****************************************************************************
+
+ - [QTBUG-75880] An anonymous function's "name" now comes directly from the
+ surrounding object pattern if applicable. This fixes some ecmascript tests
+ where functions were assigned to the key "eval" in an object.
+ - [QTBUG-75896] Fixed lookups of properties in QML singletons.
+ - [QTBUG-48809] We now print a warning when encountering a non-relative URL
+ in a qmldir file. You should use relative paths.
+ - [QTBUG-75609] Improved the cache for looking up attached properties objects,
+ to fix a performance regression in Qt Quick Layouts.
+ - [QTBUG-75392] Fixed a crash caused by std::function.
+ - [QTBUG-74048] Fixed a crash in QJSEngine::evaluate.
+ - [QTBUG-75501] lupdate now works better with the Qt Quick compiler.
+ - [QTBUG-75393] Fixed debugging of named signal arguments in Connections.
+ - [QTBUG-75410] Fixed maximum call stack depth for clang ASAN builds.
+ - [QTBUG-74815] We now allow creation of variants from non-singleton
+ QQmlTypeWrappers.
+ - [QTBUG-74815] Unknown types are no longer mis-identified as "null".
+ - [QTBUG-75335] Fixed a crash related to optimized heap lookups.
+ - [QTBUG-73217] The "QML debugging is enabled" warning is printed
+ normally rather than via a log message, which works better with
+ static builds.
+ - [QTBUG-75176] Fixed a crash on exit related to attached properties
+ on static builds.
+ - [QTBUG-75203] Fixed a crash when accessing invalid properties through
+ QObjectWrapper
+ - [QTBUG-71116] Errors in fetchOrCreateTypeForUrl are no longer fatal.
+ - [QTBUG-75121] Fixed an invalid capture in ECMAScript
+ string.replace(RegExp, backref)
+ - [QTBUG-74876] Fixed a crash in LinkBuffer's performFinalization.
+ - [QTBUG-74876] Fixed a memory leak when emitting QImage or QPixmap
+ as a signal argument.
+ - [QDS-589] qmlscene now supports file selectors.
+ - [QTBUG-74867] We now detect and reject cyclic aliases to avoid
+ infinite recursion.
+ - [QTBUG-74884] Configuration with -no-feature-delegate-model now works.
+ - [QTBUG-75030] Fixed an arithmetic exception related to bindings.
+
+****************************************************************************
+* QtQuick *
+****************************************************************************
+
+ - [QTBUG-73768] Fixed a failing assertion in BorderImage when any border size
+ exceeds source image size.
+ - [QTBUG-75770] MouseArea no longer mis-identifies fast drags as double clicks.
+ - [QTBUG-75002] Accessibility: StaticText nodes are now properly marked as
+ read-only.
+ - [QTBUG-70083] Replaced PinchHandler qCInfo messages with qCDebug.
+ - [QTBUG-70083] Fixed the "no points" warning when using native gestures.
+ - [QTBUG-73182] Fixed a memory leak by optimizing storage of
+ QQuickEventPoint instances.
+ - [QTBUG-65761] Fixed input handling in QWebEngineView on eglfs.
+ - [QTBUG-51993] Canvas3D now works properly inside QQuickWidget.
+ - [QTBUG-74966] DragHandler no longer makes its target jump if you
+ start dragging in the margin area.
+ - [QTBUG-74679] Touch cancel now results in an ungrab event, so that
+ any parent flickable can filter the event, reset its state and be ready
+ to scroll again.
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index ece2f0d692..7a784a2b35 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -263,7 +263,6 @@ QAbstractAnimationJob::QAbstractAnimationJob()
, m_currentLoopStartTime(0)
, m_nextSibling(nullptr)
, m_previousSibling(nullptr)
- , m_wasDeleted(nullptr)
, m_hasRegisteredTimer(false)
, m_isPause(false)
, m_isGroup(false)
@@ -277,9 +276,6 @@ QAbstractAnimationJob::QAbstractAnimationJob()
QAbstractAnimationJob::~QAbstractAnimationJob()
{
- if (m_wasDeleted)
- *m_wasDeleted = true;
-
//we can't call stop here. Otherwise we get pure virtual calls
if (m_state != Stopped) {
State oldState = m_state;
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index 0be6ca96ea..d046ce9def 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -52,6 +52,7 @@
//
#include <private/qtqmlglobal_p.h>
+#include <private/qanimationjobutil_p.h>
#include <QtCore/QObject>
#include <QtCore/private/qabstractanimation_p.h>
#include <vector>
@@ -130,6 +131,7 @@ public:
bool isRenderThreadJob() const { return m_isRenderThreadJob; }
bool isRenderThreadProxy() const { return m_isRenderThreadProxy; }
+ SelfDeletable m_selfDeletable;
protected:
virtual void updateCurrentTime(int) {}
virtual void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState);
@@ -174,7 +176,6 @@ protected:
QAbstractAnimationJob *m_previousSibling;
QQmlAnimationTimer *m_timer = nullptr;
- bool *m_wasDeleted;
bool m_hasRegisteredTimer:1;
bool m_isPause:1;
bool m_isGroup:1;
diff --git a/src/qml/animations/qanimationjobutil_p.h b/src/qml/animations/qanimationjobutil_p.h
index e3d6fe9178..83cf3b246f 100644
--- a/src/qml/animations/qanimationjobutil_p.h
+++ b/src/qml/animations/qanimationjobutil_p.h
@@ -51,20 +51,40 @@
// We mean it.
//
+#include <type_traits>
+
QT_REQUIRE_CONFIG(qml_animation);
-#define RETURN_IF_DELETED(func) \
+// SelfDeletable is used for self-destruction detection along with
+// ACTION_IF_DELETED and RETURN_IF_DELETED macros. While using, the objects
+// under test should have a member m_selfDeletable of type SelfDeletable
+struct SelfDeletable {
+ ~SelfDeletable() {
+ if (m_wasDeleted)
+ *m_wasDeleted = true;
+ }
+ bool *m_wasDeleted = nullptr;
+};
+
+// \param p pointer to object under test, which should have a member m_selfDeletable of type SelfDeletable
+// \param func statements or functions that to be executed under test.
+// \param action post process if p was deleted under test.
+#define ACTION_IF_DELETED(p, func, action) \
{ \
- bool *prevWasDeleted = m_wasDeleted; \
+ static_assert(std::is_same<decltype((p)->m_selfDeletable), SelfDeletable>::value, "m_selfDeletable must be SelfDeletable");\
+ bool *prevWasDeleted = (p)->m_selfDeletable.m_wasDeleted; \
bool wasDeleted = false; \
- m_wasDeleted = &wasDeleted; \
- func; \
+ (p)->m_selfDeletable.m_wasDeleted = &wasDeleted; \
+ {func;} \
if (wasDeleted) { \
if (prevWasDeleted) \
*prevWasDeleted = true; \
- return; \
+ {action;} \
} \
- m_wasDeleted = prevWasDeleted; \
+ (p)->m_selfDeletable.m_wasDeleted = prevWasDeleted; \
}
+#define RETURN_IF_DELETED(func) \
+ACTION_IF_DELETED(this, func, return)
+
#endif // QANIMATIONJOBUTIL_P_H
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index d6dddc3f1c..7e1f54f07e 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -206,8 +206,8 @@ public:
axisData->move.setValue(-flickable->contentX());
else
axisData->move.setValue(-flickable->contentY());
- cancel();
active = false;
+ cancel();
}
protected:
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 431cb80a75..c20f778a8f 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2232,7 +2232,10 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co
if (item->scheduledTransitionType() == QQuickItemViewTransitioner::MoveTransition)
repositionItemAt(item, item->index, 0);
- if (item->prepareTransition(transitioner, viewBounds)) {
+ bool success = false;
+ ACTION_IF_DELETED(item, success = item->prepareTransition(transitioner, viewBounds), return success);
+
+ if (success) {
item->releaseAfterTransition = true;
return true;
}
diff --git a/src/quick/items/qquickitemviewfxitem.cpp b/src/quick/items/qquickitemviewfxitem.cpp
index 60e9d7b115..ead4a030ac 100644
--- a/src/quick/items/qquickitemviewfxitem.cpp
+++ b/src/quick/items/qquickitemviewfxitem.cpp
@@ -56,6 +56,8 @@ QQuickItemViewFxItem::QQuickItemViewFxItem(QQuickItem *item, bool ownItem, QQuic
QQuickItemViewFxItem::~QQuickItemViewFxItem()
{
delete transitionableItem;
+ transitionableItem = nullptr;
+
if (ownItem && item) {
trackGeometry(false);
item->setParentItem(0);
diff --git a/src/quick/items/qquickitemviewfxitem_p_p.h b/src/quick/items/qquickitemviewfxitem_p_p.h
index 3bc5ba440c..3985630cda 100644
--- a/src/quick/items/qquickitemviewfxitem_p_p.h
+++ b/src/quick/items/qquickitemviewfxitem_p_p.h
@@ -54,6 +54,7 @@
#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickitemviewtransition_p.h>
+#include <private/qanimationjobutil_p.h>
QT_REQUIRE_CONFIG(quick_itemview);
@@ -94,6 +95,7 @@ public:
virtual bool contains(qreal x, qreal y) const = 0;
+ SelfDeletable m_selfDeletable;
QPointer<QQuickItem> item;
QQuickItemChangeListener *changeListener;
QQuickItemViewTransitionableItem *transitionableItem;
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index 0fde0beb75..109851608b 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -61,7 +61,6 @@ public:
QPointF m_toPos;
QQuickItemViewTransitioner::TransitionType m_type;
bool m_isTarget;
- bool *m_wasDeleted;
protected:
void finished() override;
@@ -73,14 +72,11 @@ QQuickItemViewTransitionJob::QQuickItemViewTransitionJob()
, m_item(nullptr)
, m_type(QQuickItemViewTransitioner::NoTransition)
, m_isTarget(false)
- , m_wasDeleted(nullptr)
{
}
QQuickItemViewTransitionJob::~QQuickItemViewTransitionJob()
{
- if (m_wasDeleted)
- *m_wasDeleted = true;
if (m_transitioner)
m_transitioner->runningJobs.remove(this);
}
@@ -138,13 +134,7 @@ void QQuickItemViewTransitionJob::finished()
QQuickTransitionManager::finished();
if (m_transitioner) {
- bool deleted = false;
- m_wasDeleted = &deleted;
- m_transitioner->finishedTransition(this, m_item);
- if (deleted)
- return;
- m_wasDeleted = nullptr;
-
+ RETURN_IF_DELETED(m_transitioner->finishedTransition(this, m_item));
m_transitioner = nullptr;
}
@@ -482,7 +472,7 @@ bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitio
// if transition type is not valid, the previous transition still has to be
// canceled so that the item can move immediately to the right position
item->setPosition(nextTransitionTo);
- stopTransition();
+ ACTION_IF_DELETED(this, stopTransition(), return false);
}
prepared = true;
@@ -501,12 +491,12 @@ void QQuickItemViewTransitionableItem::startTransition(QQuickItemViewTransitione
if (!transition || transition->m_type != nextTransitionType || transition->m_isTarget != isTransitionTarget) {
if (transition)
- transition->cancel();
+ RETURN_IF_DELETED(transition->cancel());
delete transition;
transition = new QQuickItemViewTransitionJob;
}
- transition->startTransition(this, index, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget);
+ RETURN_IF_DELETED(transition->startTransition(this, index, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget));
clearCurrentScheduledTransition();
}
@@ -558,7 +548,7 @@ void QQuickItemViewTransitionableItem::clearCurrentScheduledTransition()
void QQuickItemViewTransitionableItem::stopTransition()
{
if (transition)
- transition->cancel();
+ RETURN_IF_DELETED(transition->cancel());
clearCurrentScheduledTransition();
resetNextTransitionPos();
}
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 29a62f7f10..0c7a9cad75 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -60,6 +60,7 @@ QT_REQUIRE_CONFIG(quick_viewtransitions);
#include <QtQml/qqml.h>
#include <private/qqmlguard_p.h>
#include <private/qquicktransition_p.h>
+#include <private/qanimationjobutil_p.h>
QT_BEGIN_NAMESPACE
@@ -157,6 +158,7 @@ public:
bool prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds);
void startTransition(QQuickItemViewTransitioner *transitioner, int index);
+ SelfDeletable m_selfDeletable;
QPointF nextTransitionTo;
QPointF lastMovedTo;
QPointF nextTransitionFrom;
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index 2e5fdbbe6b..af3b901af4 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -238,12 +238,13 @@ void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color)
renderableNode(m_background)->markMaterialDirty();
}
-void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect)
+void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect, qreal devicePixelRatio)
{
- if (m_background->rect().toRect() == rect)
+ if (m_background->rect().toRect() == rect && m_devicePixelRatio == devicePixelRatio)
return;
m_background->setRect(rect);
- renderableNode(m_background)->markGeometryDirty();
+ m_devicePixelRatio = devicePixelRatio;
+ renderableNode(m_background)->markGeometryDirty();
// Invalidate the whole scene when the background is resized
markDirty();
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
index 99204ef25e..875569454f 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
@@ -83,7 +83,7 @@ protected:
QRegion optimizeRenderList();
void setBackgroundColor(const QColor &color);
- void setBackgroundRect(const QRect &rect);
+ void setBackgroundRect(const QRect &rect, qreal devicePixelRatio);
QColor backgroundColor();
QRect backgroundRect();
// only known after calling optimizeRenderList()
@@ -105,6 +105,7 @@ private:
QRegion m_dirtyRegion;
QRegion m_obscuredRegion;
+ qreal m_devicePixelRatio = 1;
bool m_isOpaque = false;
QSGSoftwareRenderableNodeUpdater *m_nodeUpdater;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
index bb4afc8301..4a6d73ec59 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
@@ -79,7 +79,7 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target)
QElapsedTimer renderTimer;
// Setup background item
- setBackgroundRect(m_projectionRect.normalized());
+ setBackgroundRect(m_projectionRect.normalized(), qreal(1));
setBackgroundColor(clearColor());
renderTimer.start();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
index e9ed52d428..df129cbfee 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
@@ -114,7 +114,8 @@ void QSGSoftwareRenderer::render()
setBackgroundColor(clearColor());
setBackgroundRect(QRect(0, 0,
m_paintDevice->width() / m_paintDevice->devicePixelRatioF(),
- m_paintDevice->height() / m_paintDevice->devicePixelRatioF()));
+ m_paintDevice->height() / m_paintDevice->devicePixelRatioF()),
+ m_paintDevice->devicePixelRatioF());
// Build Renderlist
// The renderlist is created by visiting each node in the tree and when a
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
index 7186ee4265..48ec8f01d3 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
@@ -156,6 +156,10 @@ void QSGDefaultImageNode::setTexture(QSGTexture *texture)
m_isAtlasTexture = texture->isAtlasTexture();
if (wasAtlas || m_isAtlasTexture)
dirty |= DirtyGeometry;
+ // The geometry has also changed if the texture size changed.
+ if (m_textureSize != texture->textureSize())
+ dirty |= DirtyGeometry;
+ m_textureSize = texture->textureSize();
markDirty(dirty);
}
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
index cb23e759d3..7b26daf541 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
@@ -95,6 +95,7 @@ private:
QSGTextureMaterial m_material;
QRectF m_rect;
QRectF m_sourceRect;
+ QSize m_textureSize;
TextureCoordinatesTransformMode m_texCoordMode;
uint m_isAtlasTexture : 1;
uint m_ownsTexture : 1;
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp
index e51de1a02a..0ee7e57997 100644
--- a/src/quick/util/qquicktransitionmanager.cpp
+++ b/src/quick/util/qquicktransitionmanager.cpp
@@ -47,6 +47,7 @@
#include <private/qqmlproperty_p.h>
#include <QtCore/qdebug.h>
+#include <private/qanimationjobutil_p.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,7 @@ void QQuickTransitionManager::setState(QQuickState *s)
QQuickTransitionManager::~QQuickTransitionManager()
{
delete d->transitionInstance;
+ d->transitionInstance = nullptr;
delete d; d = nullptr;
}
@@ -129,7 +131,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
QQuickTransition *transition,
QObject *defaultTarget)
{
- cancel();
+ RETURN_IF_DELETED(cancel());
// The copy below is ON PURPOSE, because firing actions might involve scripts that modify the list.
QQuickStateOperation::ActionList applyList = list;
@@ -154,7 +156,6 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
//
// This doesn't catch everything, and it might be a little fragile in
// some cases - but whatcha going to do?
-
if (transition && !d->bindingsList.isEmpty()) {
// Apply all the property and binding changes
@@ -258,7 +259,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
void QQuickTransitionManager::cancel()
{
if (d->transitionInstance && d->transitionInstance->isRunning())
- d->transitionInstance->stop();
+ RETURN_IF_DELETED(d->transitionInstance->stop());
for (const QQuickStateAction &action : qAsConst(d->bindingsList)) {
if (action.toBinding && action.deletableToBinding) {
diff --git a/src/quick/util/qquicktransitionmanager_p_p.h b/src/quick/util/qquicktransitionmanager_p_p.h
index 89317e1e07..fc00ec8a52 100644
--- a/src/quick/util/qquicktransitionmanager_p_p.h
+++ b/src/quick/util/qquicktransitionmanager_p_p.h
@@ -52,6 +52,7 @@
//
#include "qquickanimation_p.h"
+#include <private/qanimationjobutil_p.h>
QT_BEGIN_NAMESPACE
@@ -70,6 +71,7 @@ public:
void cancel();
+ SelfDeletable m_selfDeletable;
protected:
virtual void finished();
diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp
index 262d0b3e9a..74cbf52a95 100644
--- a/src/quickshapes/qquickshape.cpp
+++ b/src/quickshapes/qquickshape.cpp
@@ -48,6 +48,13 @@
#include <QOpenGLFunctions>
#include <QLoggingCategory>
+#if defined(QT_STATIC)
+static void initResources()
+{
+ Q_INIT_RESOURCE(qtquickshapes);
+}
+#endif
+
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(QQSHAPE_LOG_TIME_DIRTY_SYNC, "qt.shape.time.sync")
@@ -662,7 +669,7 @@ struct QQuickShapeResourceInitializer
QQuickShapeResourceInitializer()
{
#if defined(QT_STATIC)
- Q_INIT_RESOURCE(qtquickshapes);
+ initResources();
#endif
}
};
diff --git a/tests/auto/quick/qquickanimations/data/animationJobSelfDestructionBug.qml b/tests/auto/quick/qquickanimations/data/animationJobSelfDestructionBug.qml
new file mode 100644
index 0000000000..259871785b
--- /dev/null
+++ b/tests/auto/quick/qquickanimations/data/animationJobSelfDestructionBug.qml
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.11
+import QtQuick.Window 2.11
+
+Window {
+ id: root
+ property alias timer : timer
+ property variant ops: [{'op': 'add', 'count': 3}, {'op': 'add', 'count': 6}, {'op': 'rem', 'count': 4}, {'op': 'rem', 'count': 1}, {'op': 'rem', 'count': 3}]
+ property int opIndex : 0
+ width: 400
+ height: 600
+
+ ListModel {
+ id: theModel
+ }
+
+ Timer {
+ id: timer
+ interval: 100
+ running: false
+ repeat: true
+ onTriggered: {
+ if (opIndex >= ops.length) {
+ timer.stop()
+ return
+ }
+ let op = ops[opIndex]
+ for (var i = 0; i < op.count; ++i) {
+ if (op.op === "add")
+ theModel.append({"name": "opIndex " + opIndex})
+ else
+ theModel.remove(0, 1);
+ }
+ opIndex = opIndex + 1
+ }
+ }
+
+ ListView {
+ anchors.top: parent.top
+ anchors.right: parent.right
+ height: 600
+ anchors.left: parent.horizontalCenter
+ spacing: 4
+ model: theModel
+ header: Text {
+ text: "YAnimator"
+ }
+ add: Transition {
+ NumberAnimation { property: "scale"; from: 0; to: 1; duration: 200 }
+ NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
+ }
+ displaced: Transition {
+ YAnimator { duration: 500 }
+ NumberAnimation { property: "opacity"; to: 1.0; duration: 500 }
+ NumberAnimation { property: "scale"; to: 1.0; duration: 500 }
+ }
+ remove: Transition {
+ NumberAnimation { property: "opacity"; to: 0; duration: 200 }
+ NumberAnimation { property: "scale"; to: 0; duration: 200 }
+ }
+ delegate: Rectangle {
+ width: 200
+ height: 20
+ color:"red"
+ Text {
+ anchors.centerIn: parent
+ text: name
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimations/qquickanimations.pro b/tests/auto/quick/qquickanimations/qquickanimations.pro
index 8bb1f47af5..cf9c87a305 100644
--- a/tests/auto/quick/qquickanimations/qquickanimations.pro
+++ b/tests/auto/quick/qquickanimations/qquickanimations.pro
@@ -12,6 +12,7 @@ QT += core-private gui-private qml-private quick-private testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
+ data/animationJobSelfDestructionBug.qml\
data/attached.qml \
data/badproperty1.qml \
data/badproperty2.qml \
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 961506372a..181d40e9ce 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -109,6 +109,7 @@ private slots:
void unsetAnimatorProxyJobWindow();
void finished();
void replacingTransitions();
+ void animationJobSelfDestruction();
};
#define QTIMED_COMPARE(lhs, rhs) do { \
@@ -1723,6 +1724,26 @@ void tst_qquickanimations::replacingTransitions()
QCOMPARE(model->count(), 3);
}
+void tst_qquickanimations::animationJobSelfDestruction()
+{
+ // Don't crash
+ QQmlEngine engine;
+ engine.clearComponentCache();
+ QQmlComponent c(&engine, testFileUrl("animationJobSelfDestructionBug.qml"));
+ QScopedPointer<QQuickWindow> win(qobject_cast<QQuickWindow*>(c.create()));
+ if (!c.errors().isEmpty())
+ qDebug() << c.errorString();
+ QVERIFY(win);
+ win->setTitle(QTest::currentTestFunction());
+ win->show();
+ QVERIFY(QTest::qWaitForWindowExposed(win.data()));
+ QQmlTimer *timer = win->property("timer").value<QQmlTimer*>();
+ QVERIFY(timer);
+ QCOMPARE(timer->isRunning(), false);
+ timer->start();
+ QTest::qWait(1000);
+}
+
QTEST_MAIN(tst_qquickanimations)
#include "tst_qquickanimations.moc"