diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-09-23 23:10:02 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-09-26 07:54:08 +0000 |
commit | 5322ad410a78e43a86bb00b9765698c59f9449cb (patch) | |
tree | 291097cd61b8ce4fb3fd547da5cf1dab55eaae74 /src/quicktemplates2/qquickstackview_p.cpp | |
parent | 56bddc7fa4b0222d38fcc5e083b9588c3d2f8b93 (diff) |
Fix a crash in StackView::pop()
If an item is still activating (from a previous pop) when it gets
already popped out, we must not set the deactivating status before
calling prepareTransition(). This method cancels and finishes the
ongoing activation transition, and if the status says that the item
was deactivating, the item gets destroyed in the middle of preparing
for the deactivation transition.
Let prepareTransition() cancel any ongoing transition first, and then
set the status after the preparation. The cleanest way is to pass
the target status to startTransition() and completeTransition().
Task-number: QTBUG-56158
Change-Id: Id52752200b650ea9f84659bbf43431f8a8b22f1e
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickstackview_p.cpp')
-rw-r--r-- | src/quicktemplates2/qquickstackview_p.cpp | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp index c1b68652..3709b988 100644 --- a/src/quicktemplates2/qquickstackview_p.cpp +++ b/src/quicktemplates2/qquickstackview_p.cpp @@ -251,8 +251,9 @@ bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitio return false; } -void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner) +void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status) { + setStatus(status); if (transitioner) QQuickItemViewTransitionableItem::startTransition(transitioner, index); } @@ -415,27 +416,23 @@ void QQuickStackViewPrivate::popTransition(QQuickStackElement *enter, QQuickStac { ensureTransitioner(); - if (exit) { - exit->removal = true; - exit->setStatus(QQuickStackView::Deactivating); + if (exit) exit->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, true); - } - if (enter) { - enter->setStatus(QQuickStackView::Activating); + if (enter) enter->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); - } if (exit) { + exit->removal = true; if (immediate || !exit->item || !exit->prepareTransition(transitioner, viewBounds)) - completeTransition(exit, transitioner->removeTransition); + completeTransition(exit, transitioner->removeTransition, QQuickStackView::Deactivating); else - exit->startTransition(transitioner); + exit->startTransition(transitioner, QQuickStackView::Deactivating); } if (enter) { if (immediate || !enter->item || !enter->prepareTransition(transitioner, QRectF())) - completeTransition(enter, transitioner->removeDisplacedTransition); + completeTransition(enter, transitioner->removeDisplacedTransition, QQuickStackView::Activating); else - enter->startTransition(transitioner); + enter->startTransition(transitioner, QQuickStackView::Activating); } if (transitioner) { @@ -448,26 +445,22 @@ void QQuickStackViewPrivate::pushTransition(QQuickStackElement *enter, QQuickSta { ensureTransitioner(); - if (enter) { - enter->setStatus(QQuickStackView::Activating); + if (enter) enter->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); - } - if (exit) { - exit->setStatus(QQuickStackView::Deactivating); + if (exit) exit->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false); - } if (enter) { if (immediate || !enter->item || !enter->prepareTransition(transitioner, viewBounds)) - completeTransition(enter, transitioner->addTransition); + completeTransition(enter, transitioner->addTransition, QQuickStackView::Activating); else - enter->startTransition(transitioner); + enter->startTransition(transitioner, QQuickStackView::Activating); } if (exit) { if (immediate || !exit->item || !exit->prepareTransition(transitioner, QRectF())) - completeTransition(exit, transitioner->addDisplacedTransition); + completeTransition(exit, transitioner->addDisplacedTransition, QQuickStackView::Deactivating); else - exit->startTransition(transitioner); + exit->startTransition(transitioner, QQuickStackView::Deactivating); } if (transitioner) { @@ -480,27 +473,23 @@ void QQuickStackViewPrivate::replaceTransition(QQuickStackElement *enter, QQuick { ensureTransitioner(); - if (exit) { - exit->removal = true; - exit->setStatus(QQuickStackView::Deactivating); + if (exit) exit->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); - } - if (enter) { - enter->setStatus(QQuickStackView::Activating); + if (enter) enter->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true); - } if (exit) { + exit->removal = true; if (immediate || !exit->item || !exit->prepareTransition(transitioner, QRectF())) - completeTransition(exit, transitioner->moveDisplacedTransition); + completeTransition(exit, transitioner->moveDisplacedTransition, QQuickStackView::Deactivating); else - exit->startTransition(transitioner); + exit->startTransition(transitioner, QQuickStackView::Deactivating); } if (enter) { if (immediate || !enter->item || !enter->prepareTransition(transitioner, viewBounds)) - completeTransition(enter, transitioner->moveTransition); + completeTransition(enter, transitioner->moveTransition, QQuickStackView::Activating); else - enter->startTransition(transitioner); + enter->startTransition(transitioner, QQuickStackView::Activating); } if (transitioner) { @@ -509,8 +498,9 @@ void QQuickStackViewPrivate::replaceTransition(QQuickStackElement *enter, QQuick } } -void QQuickStackViewPrivate::completeTransition(QQuickStackElement *element, QQuickTransition *transition) +void QQuickStackViewPrivate::completeTransition(QQuickStackElement *element, QQuickTransition *transition, QQuickStackView::Status status) { + element->setStatus(status); if (transition) { // TODO: add a proper way to complete a transition QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations(); |