aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickstackview_p.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-09-23 23:10:02 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2016-09-26 07:54:08 +0000
commit5322ad410a78e43a86bb00b9765698c59f9449cb (patch)
tree291097cd61b8ce4fb3fd547da5cf1dab55eaae74 /src/quicktemplates2/qquickstackview_p.cpp
parent56bddc7fa4b0222d38fcc5e083b9588c3d2f8b93 (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.cpp58
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();