aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@theqtcompany.com>2015-01-27 18:09:56 +0100
committerMitch Curtis <mitch.curtis@digia.com>2015-01-28 11:54:41 +0000
commitfea8c9026def98748f700e33e9fb41249be2b3f2 (patch)
tree7cd61251f12d1f083eaa58576e256c757c6092c9
parentdd017ee946aaa7f968aa844a54b394f88109c150 (diff)
Ensure that Canvas has the correct size with complex bindings.
When a Canvas is a child of an item with certain width and height values (as described in the bug report), it won't paint correctly. For example, the order of events might occur like so: 1. Canvas width set to 1 2. Canvas height set to 1 3. Canvas width set to 32, which causes the height to also be set to 32 Every size change causes QQuickCanvasItem::geometryChanged() to be called, but the third event above causes it to be called recursively, such that the most nested call results in the size being 32x32, but then the execution returns to the first call and 32x1 is used instead, overwriting the correct size. We fix this by setting the new canvas size to width() and height(), ignoring the recursion and instead using the latest size of the item. Change-Id: Iebbcbfaa3217319b32b97f6b68f7a8af197a0e89 Task-number: QTBUG-42878 Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp4
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml38
2 files changed, 40 insertions, 2 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 4b28517701..b39c4e49f8 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -592,7 +592,9 @@ void QQuickCanvasItem::geometryChanged(const QRectF &newGeometry, const QRectF &
QQuickItem::geometryChanged(newGeometry, oldGeometry);
- QSizeF newSize = newGeometry.size();
+ // Due to indirect recursion, newGeometry may be outdated
+ // after this call, so we use width and height instead.
+ QSizeF newSize = QSizeF(width(), height());
if (!d->hasCanvasSize && d->canvasSize != newSize) {
d->canvasSize = newSize;
emit canvasSizeChanged();
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
index 79c89bb2fc..5960e53557 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
@@ -1,5 +1,10 @@
import QtQuick 2.0
+Item {
+ id: container
+ width: 200
+ height: 200
+
CanvasTestCase {
id:testCase
name: "canvas"
@@ -641,5 +646,36 @@ CanvasTestCase {
fail(exception.message);
}
}
-}
+ property Component implicitlySizedComponent: Item {
+ implicitWidth: 32
+ implicitHeight: implicitWidth
+ anchors.centerIn: parent
+
+ property alias canvas: canvas
+
+ Canvas {
+ id: canvas
+ width: Math.max(1, Math.min(parent.width, parent.height))
+ height: width
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ ctx.beginPath();
+ ctx.fillRect(0, 0, width, height);
+ }
+ }
+ }
+
+ function test_implicitlySizedParent() {
+ var implicitlySizedItem = implicitlySizedComponent.createObject(container);
+ verify(implicitlySizedItem);
+
+ var xCenter = implicitlySizedItem.width / 2;
+ var yCenter = implicitlySizedItem.height / 2;
+ waitForRendering(implicitlySizedItem);
+ comparePixel(implicitlySizedItem.canvas.context, xCenter, yCenter, 0, 0, 0, 255);
+ }
+}
+}