summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJan Arve Saether <jan-arve.saether@digia.com>2014-08-21 10:57:23 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-09-03 16:21:58 +0200
commita76f0ca34fde78ac64300b8bf9a75b5e1c1b6b51 (patch)
tree56e8580f13c0927a6606589de30317e3324df113 /tests
parent9d0c5e5f4f8c233f8424ef2fb2b440b07fe85594 (diff)
downloadqtquickcontrols-a76f0ca34fde78ac64300b8bf9a75b5e1c1b6b51.tar.gz
Do not crash when removing children from hidden layouts
The problem was that the proxy items (QQuickGridLayoutItem) that was added to the layout was not removed when a child item got deleted from a hidden layout. The proxy item therefore ended up having a dangling pointer to the deleted item. The solution is to also update the layout with a new list of items even when the layout is hidden. This will also fix a problem with that size hints was not correct when layouts were hidden. Note that the test included has an expected failure. This is because the case it tests is not very common and the problem is shared with positioners. The problem stems from the fact that a layouts implicit size should change when a child item is changed from implicitly hidden to explicitly hidden. Unfortuntately, QQuickItem does not notify about such changes. This is a problem independent of this crash patch fix, and I would like to address that in a separate commit. Change-Id: I67ac28b9d08208432559622c9cd412e24b197b32 Task-number: QTBUG-39045 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/controls/data/tst_rowlayout.qml81
1 files changed, 81 insertions, 0 deletions
diff --git a/tests/auto/controls/data/tst_rowlayout.qml b/tests/auto/controls/data/tst_rowlayout.qml
index 7daee7e8..9977193b 100644
--- a/tests/auto/controls/data/tst_rowlayout.qml
+++ b/tests/auto/controls/data/tst_rowlayout.qml
@@ -695,6 +695,61 @@ Item {
layout.destroy() // Do not crash
}
+ function test_sizeHintWithHiddenChildren(data) {
+ var layout = layout_sizeHint_Component.createObject(container)
+ var grid = layout.children[0]
+ var child = grid.children[0]
+
+ // Implicit sizes are not affected by the visibility of the parent layout.
+ // This is in order for the layout to know the preferred size it should show itself at.
+ compare(grid.visible, true) // LAYOUT SHOWN
+ compare(grid.implicitWidth, 2);
+ child.visible = false
+ compare(grid.implicitWidth, 0);
+ child.visible = true
+ compare(grid.implicitWidth, 2);
+
+ grid.visible = false // LAYOUT HIDDEN
+ compare(grid.implicitWidth, 2);
+ child.visible = false
+ expectFail('', 'If GridLayout is hidden, GridLayout is not notified when child is explicitly hidden')
+ compare(grid.implicitWidth, 0);
+ child.visible = true
+ compare(grid.implicitWidth, 2);
+
+ layout.destroy();
+ }
+
+ Component {
+ id: row_sizeHint_Component
+ Row {
+ Rectangle {
+ id: r1
+ color: "red"
+ width: 2
+ height: 20
+ }
+ }
+ }
+
+ function test_sizeHintWithHiddenChildrenForRow(data) {
+ var row = row_sizeHint_Component.createObject(container)
+ var child = row.children[0]
+ compare(row.visible, true) // POSITIONER SHOWN
+ compare(row.implicitWidth, 2);
+ child.visible = false
+ tryCompare(row, 'implicitWidth', 0);
+ child.visible = true
+ tryCompare(row, 'implicitWidth', 2);
+
+ row.visible = false // POSITIONER HIDDEN
+ compare(row.implicitWidth, 2);
+ child.visible = false
+ expectFail('', 'If Row is hidden, Row is not notified when child is explicitly hidden')
+ compare(row.implicitWidth, 0);
+ child.visible = true
+ compare(row.implicitWidth, 2);
+ }
Component {
id: rearrangeNestedLayouts_Component
@@ -736,7 +791,33 @@ Item {
waitForRendering(layout)
compare(itemRect(fixed), [0,0,100,20])
compare(itemRect(filler), [100,0,100,20])
+ }
+ Component {
+ id: changeChildrenOfHiddenLayout_Component
+ RowLayout {
+ property int childCount: 1
+ Repeater {
+ model: parent.childCount
+ Text {
+ text: 'Just foo it'
+ }
+ }
+ }
+ }
+ function test_changeChildrenOfHiddenLayout()
+ {
+ var layout = changeChildrenOfHiddenLayout_Component.createObject(container)
+ var child = layout.children[0]
+ waitForRendering(layout)
+ layout.visible = false
+ waitForRendering(layout)
+ // Remove and add children to the hidden layout..
+ layout.childCount = 0
+ waitForRendering(layout)
+ layout.childCount = 1
+ waitForRendering(layout)
+ layout.destroy()
}
}
}