diff --git a/Plugins/ZShell/Blobs/blobshape.cpp b/Plugins/ZShell/Blobs/blobshape.cpp index 85bebf2..d872714 100644 --- a/Plugins/ZShell/Blobs/blobshape.cpp +++ b/Plugins/ZShell/Blobs/blobshape.cpp @@ -69,6 +69,26 @@ void BlobShape::geometryChange(const QRectF& newGeometry, const QRectF& oldGeome QQuickItem::geometryChange(newGeometry, oldGeometry); updateCenteredDeformMatrix(); if (m_group) { + // Update cached values so markShapeDirty uses current geometry + const QPointF scenePos = mapToScene(QPointF(0, 0)); + if (isInvertedRect()) { + m_cachedPaddedX = static_cast(scenePos.x()); + m_cachedPaddedY = static_cast(scenePos.y()); + m_cachedPaddedW = static_cast(width()); + m_cachedPaddedH = static_cast(height()); + m_localPaddedRect = QRectF(0, 0, width(), height()); + } else { + const float hw = static_cast(width()) * 0.5f; + const float hh = static_cast(height()) * 0.5f; + const float totalPad = static_cast(m_group->smoothing()) + deformPadding(m_deformMatrix, hw, hh); + m_cachedPaddedX = static_cast(scenePos.x()) - totalPad; + m_cachedPaddedY = static_cast(scenePos.y()) - totalPad; + m_cachedPaddedW = static_cast(width()) + 2.0f * totalPad; + m_cachedPaddedH = static_cast(height()) + 2.0f * totalPad; + m_localPaddedRect = QRectF(static_cast(-totalPad), static_cast(-totalPad), + width() + 2.0 * static_cast(totalPad), height() + 2.0 * static_cast(totalPad)); + } + // Accumulate sub-pixel drift so slow movements don't desync the shader m_pendingDx += static_cast(newGeometry.x() - oldGeometry.x()); m_pendingDy += static_cast(newGeometry.y() - oldGeometry.y());