From 98c735be6e3335fd19a7fbd2a23b7938d69ecfe5 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 10 Nov 2020 16:45:59 +0100 Subject: [PATCH] QmlDesigner: Fix for high dpi and Qt 6 When grabbing the window we have to clip the window using the root item size. Depending on the window manager the window is resized. Another issue is that when grabbing the window offscreen the pixel ratio is always 1. Before we assumed that the pixel ratio of all images is the same for the host process as for the puppet. This is not necessarily anymore and we have to set and forward the correct pixel ratio. Change-Id: I36b467291ab120f825119adea4ed7db10d34266d Reviewed-by: Miikka Heikkinen --- .../qmlpuppet/container/imagecontainer.cpp | 22 ++++++++++++------- .../instances/quickitemnodeinstance.cpp | 7 ++++-- .../designercore/instances/nodeinstance.cpp | 4 +--- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp index 8348cbecb0c..8fbbbc48cf7 100644 --- a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp @@ -128,15 +128,16 @@ static void writeSharedMemory(SharedMemory *sharedMemory, const QImage &image) { sharedMemory->lock(); - qint32 headerData[5]; + qint32 headerData[6]; headerData[0] = qint32(image.sizeInBytes()); headerData[1] = image.bytesPerLine(); headerData[2] = image.size().width(); headerData[3] = image.size().height(); headerData[4] = image.format(); + headerData[5] = image.devicePixelRatio() * 100; - std::memcpy(sharedMemory->data(), headerData, 20); - std::memcpy(reinterpret_cast(sharedMemory->data()) + 20, image.constBits(), image.sizeInBytes()); + std::memcpy(sharedMemory->data(), headerData, 24); + std::memcpy(reinterpret_cast(sharedMemory->data()) + 24, image.constBits(), image.sizeInBytes()); sharedMemory->unlock(); } @@ -146,12 +147,13 @@ static void writeStream(QDataStream &out, const QImage &image) out << image.size(); out << qint32(image.format()); out << qint32(image.sizeInBytes()); + out << qint32(image.devicePixelRatio() * 100); out.writeRawData(reinterpret_cast(image.constBits()), image.sizeInBytes()); } QDataStream &operator<<(QDataStream &out, const ImageContainer &container) { - const int extraDataSize = 20; + const int extraDataSize = 24; static const bool dontUseSharedMemory = qEnvironmentVariableIsSet("DESIGNER_DONT_USE_SHARED_MEMORY"); out << container.instanceId(); @@ -183,24 +185,26 @@ static void readSharedMemory(qint32 key, ImageContainer &container) bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); - if (canAttach && sharedMemory.size() >= 20) + if (canAttach && sharedMemory.size() >= 24) { sharedMemory.lock(); - qint32 headerData[5]; - std::memcpy(headerData, sharedMemory.constData(), 20); + qint32 headerData[6]; + std::memcpy(headerData, sharedMemory.constData(), 24); qint32 byteCount = headerData[0]; // qint32 bytesPerLine = headerData[1]; qint32 imageWidth = headerData[2]; qint32 imageHeight = headerData[3]; qint32 imageFormat = headerData[4]; + qreal pixelRatio = headerData[5] / 100.0; QImage image = QImage(imageWidth, imageHeight, QImage::Format(imageFormat)); + image.setDevicePixelRatio(pixelRatio); if (image.isNull()) qDebug() << Q_FUNC_INFO << "Not able to create image:" << imageWidth << imageHeight << imageFormat; else - std::memcpy(image.bits(), reinterpret_cast(sharedMemory.constData()) + 5, byteCount); + std::memcpy(image.bits(), reinterpret_cast(sharedMemory.constData()) + 6, byteCount); container.setImage(image); @@ -215,6 +219,7 @@ static void readStream(QDataStream &in, ImageContainer &container) qint32 bytesPerLine; QSize imageSize; qint32 imageFormat; + qint32 pixelRatio; in >> bytesPerLine; in >> imageSize; @@ -224,6 +229,7 @@ static void readStream(QDataStream &in, ImageContainer &container) QImage image = QImage(imageSize, QImage::Format(imageFormat)); in.readRawData(reinterpret_cast(image.bits()), byteCount); + image.setDevicePixelRatio(pixelRatio / 100.0); container.setImage(image); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index bc91a475059..b400d8c2d25 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -428,12 +428,14 @@ QImage QuickItemNodeInstance::renderImage() const nodeInstanceServer()->quickView()->afterRendering(); } + renderImage.setDevicePixelRatio(devicePixelRatio); #else renderImage = nodeInstanceServer()->quickView()->grabWindow(); + renderImage = renderImage.copy(renderBoundingRect.toRect()); + /* When grabbing an offscren window the device pixel ratio is 1 */ + renderImage.setDevicePixelRatio(1); #endif - renderImage.setDevicePixelRatio(devicePixelRatio); - return renderImage; } @@ -462,6 +464,7 @@ QImage QuickItemNodeInstance::renderPreviewImage(const QSize &previewImageSize) } #else image = nodeInstanceServer()->quickView()->grabWindow(); + image = image.copy(previewItemBoundingRect.toRect()); #endif image = image.scaledToWidth(size.width()); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp index b74179fdef8..91bb2c30711 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp @@ -473,9 +473,7 @@ QPixmap NodeInstance::blurredRenderPixmap() const void NodeInstance::setRenderPixmap(const QImage &image) { d->renderPixmap = QPixmap::fromImage(image); -#ifndef QMLDESIGNER_TEST - d->renderPixmap.setDevicePixelRatio(QmlDesignerPlugin::formEditorDevicePixelRatio()); -#endif + d->blurredRenderPixmap = QPixmap(); }