diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 13cdb4b9b93..aa786bac6aa 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -348,6 +348,14 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) ServerNodeInstance instance = instanceForObject(item); const auto childInstances = instance.childItems(); + // Setting layer enabled to false messes up the bounding rect. + // Therefore we calculate it upfront. + QRectF renderBoundingRect; + if (instance.isValid()) + renderBoundingRect = instance.boundingRect(); + else + renderBoundingRect = item->boundingRect(); + // Hide immediate children that have instances and are QQuickItems so we get only // the parent item's content, as compositing is handled on creator side. for (const auto &childInstance : childInstances) { @@ -372,11 +380,15 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) QSGRenderContext *rc = QQuickWindowPrivate::get(m_viewData.window.data())->context; QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc); layer->setItem(pItem->itemNode()); - QSizeF itemSize = QSizeF(item->width(), item->height()); - layer->setRect(QRectF(0, itemSize.height(), itemSize.width(), -itemSize.height())); + + layer->setRect(QRectF(renderBoundingRect.x(), + renderBoundingRect.y() + renderBoundingRect.height(), + renderBoundingRect.width(), + -renderBoundingRect.height())); + const QSize minSize = rc->sceneGraphContext()->minimumFBOSize(); - layer->setSize(QSize(qMax(minSize.width(), int(itemSize.width())), - qMax(minSize.height(), int(itemSize.height())))); + layer->setSize(QSize(qMax(minSize.width(), int(renderBoundingRect.width())), + qMax(minSize.height(), int(renderBoundingRect.height())))); layer->scheduleUpdate(); if (layer->updateTexture()) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index ab38b33aafe..33bc2ee156c 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -28,6 +28,9 @@ #include +#include +#include + #include #include #include @@ -476,11 +479,12 @@ QImage QuickItemNodeInstance::renderImage() const } renderImage.setDevicePixelRatio(devicePixelRatio); #else - if (s_unifiedRenderPath) + if (s_unifiedRenderPath) { renderImage = nodeInstanceServer()->grabWindow(); - else + renderImage = renderImage.copy(renderBoundingRect.toRect()); + } else { renderImage = nodeInstanceServer()->grabItem(quickItem()); - renderImage = renderImage.copy(renderBoundingRect.toRect()); + } /* When grabbing an offscren window the device pixel ratio is 1 */ renderImage.setDevicePixelRatio(1); @@ -613,6 +617,34 @@ static inline bool isRectangleSane(const QRectF &rect) return rect.isValid() && (rect.width() < 10000) && (rect.height() < 10000); } +static bool isEffectItem(QQuickItem *item) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + Q_UNUSED(item) + return false; +#else + if (qobject_cast(item)) + return true; + + const auto propName = "source"; + + QQmlProperty prop(item, QString::fromLatin1(propName)); + if (!prop.isValid()) + return false; + + QQuickShaderEffectSource *source = prop.read().value(); + + if (source && source->sourceItem()) { + QQuickItemPrivate *pItem = QQuickItemPrivate::get(source->sourceItem()); + + if (pItem && pItem->layer() && pItem->layer()->enabled() && pItem->layer()->effect()) + return true; + } + + return false; +#endif +} + QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) const { QRectF boundingRect = parentItem->boundingRect(); @@ -620,8 +652,9 @@ QRectF QuickItemNodeInstance::boundingRectWithStepChilds(QQuickItem *parentItem) boundingRect = boundingRect.united(QRectF(QPointF(0, 0), size())); for (QQuickItem *childItem : parentItem->childItems()) { - if (!nodeInstanceServer()->hasInstanceForObject(childItem)) { - QRectF transformedRect = childItem->mapRectToItem(parentItem, boundingRectWithStepChilds(childItem)); + if (!nodeInstanceServer()->hasInstanceForObject(childItem) && !isEffectItem(childItem)) { + QRectF transformedRect = childItem->mapRectToItem(parentItem, + boundingRectWithStepChilds(childItem)); if (isRectangleSane(transformedRect)) boundingRect = boundingRect.united(transformedRect); }