diff --git a/src/decorationitem.cpp b/src/decorationitem.cpp index 55a99bdbea..d80ceacc9f 100644 --- a/src/decorationitem.cpp +++ b/src/decorationitem.cpp @@ -68,6 +68,12 @@ void DecorationRenderer::resetDamage() m_damage = QRegion(); } +qreal DecorationRenderer::effectiveDevicePixelRatio() const +{ + // QPainter won't let paint with a device pixel ratio less than 1. + return std::max(qreal(1.0), devicePixelRatio()); +} + qreal DecorationRenderer::devicePixelRatio() const { return m_devicePixelRatio; @@ -107,7 +113,7 @@ QImage DecorationRenderer::renderToImage(const QRect &geo) image.fill(Qt::transparent); QPainter p(&image); p.setRenderHint(QPainter::Antialiasing); - p.setWindow(QRect(geo.topLeft(), geo.size() * qPainterEffectiveDevicePixelRatio(&p))); + p.setWindow(QRect(geo.topLeft(), geo.size() * effectiveDevicePixelRatio())); p.setClipRect(geo); renderToPainter(&p, geo); return image; @@ -230,7 +236,7 @@ WindowQuadList DecorationItem::buildQuads() const } QRect left, top, right, bottom; - const qreal devicePixelRatio = m_renderer->devicePixelRatio(); + const qreal devicePixelRatio = m_renderer->effectiveDevicePixelRatio(); const int texturePad = DecorationRenderer::TexturePad; if (const AbstractClient *client = qobject_cast(m_window)) { diff --git a/src/decorationitem.h b/src/decorationitem.h index 21d4da01cb..b9a5c98686 100644 --- a/src/decorationitem.h +++ b/src/decorationitem.h @@ -38,6 +38,7 @@ public: void addDamage(const QRegion ®ion); void resetDamage(); + qreal effectiveDevicePixelRatio() const; qreal devicePixelRatio() const; void setDevicePixelRatio(qreal dpr); diff --git a/src/scenes/opengl/scene_opengl.cpp b/src/scenes/opengl/scene_opengl.cpp index b1cff70263..8e585f64c7 100644 --- a/src/scenes/opengl/scene_opengl.cpp +++ b/src/scenes/opengl/scene_opengl.cpp @@ -1536,9 +1536,10 @@ void SceneOpenGLDecorationRenderer::render(const QRegion ®ion) QRect left, top, right, bottom; client()->client()->layoutDecorationRects(left, top, right, bottom); - const int topHeight = std::ceil(top.height() * devicePixelRatio()); - const int bottomHeight = std::ceil(bottom.height() * devicePixelRatio()); - const int leftWidth = std::ceil(left.width() * devicePixelRatio()); + const qreal devicePixelRatio = effectiveDevicePixelRatio(); + const int topHeight = std::ceil(top.height() * devicePixelRatio); + const int bottomHeight = std::ceil(bottom.height() * devicePixelRatio); + const int leftWidth = std::ceil(left.width() * devicePixelRatio); const QPoint topPosition(0, 0); const QPoint bottomPosition(0, topPosition.y() + topHeight + (2 * TexturePad)); @@ -1547,14 +1548,15 @@ void SceneOpenGLDecorationRenderer::render(const QRegion ®ion) const QRect dirtyRect = region.boundingRect(); - renderPart(top.intersected(dirtyRect), top, topPosition); - renderPart(bottom.intersected(dirtyRect), bottom, bottomPosition); - renderPart(left.intersected(dirtyRect), left, leftPosition, true); - renderPart(right.intersected(dirtyRect), right, rightPosition, true); + renderPart(top.intersected(dirtyRect), top, topPosition, devicePixelRatio); + renderPart(bottom.intersected(dirtyRect), bottom, bottomPosition, devicePixelRatio); + renderPart(left.intersected(dirtyRect), left, leftPosition, devicePixelRatio, true); + renderPart(right.intersected(dirtyRect), right, rightPosition, devicePixelRatio, true); } void SceneOpenGLDecorationRenderer::renderPart(const QRect &rect, const QRect &partRect, - const QPoint &textureOffset, bool rotated) + const QPoint &textureOffset, + qreal devicePixelRatio, bool rotated) { if (!rect.isValid()) { return; @@ -1567,7 +1569,7 @@ void SceneOpenGLDecorationRenderer::renderPart(const QRect &rect, const QRect &p int verticalPadding = padding.top() + padding.bottom(); int horizontalPadding = padding.left() + padding.right(); - QSize imageSize = rect.size() * devicePixelRatio(); + QSize imageSize = rect.size() * devicePixelRatio; if (rotated) { imageSize = QSize(imageSize.height(), imageSize.width()); } @@ -1575,12 +1577,12 @@ void SceneOpenGLDecorationRenderer::renderPart(const QRect &rect, const QRect &p paddedImageSize.rheight() += verticalPadding; paddedImageSize.rwidth() += horizontalPadding; QImage image(paddedImageSize, QImage::Format_ARGB32_Premultiplied); - image.setDevicePixelRatio(devicePixelRatio()); + image.setDevicePixelRatio(devicePixelRatio); image.fill(Qt::transparent); QRect padClip = QRect(padding.left(), padding.top(), imageSize.width(), imageSize.height()); QPainter painter(&image); - const qreal inverseScale = 1.0 / devicePixelRatio(); + const qreal inverseScale = 1.0 / devicePixelRatio; painter.scale(inverseScale, inverseScale); painter.setRenderHint(QPainter::Antialiasing); painter.setClipRect(padClip); @@ -1589,7 +1591,7 @@ void SceneOpenGLDecorationRenderer::renderPart(const QRect &rect, const QRect &p painter.translate(0, imageSize.height()); painter.rotate(-90); } - painter.scale(devicePixelRatio(), devicePixelRatio()); + painter.scale(devicePixelRatio, devicePixelRatio); painter.translate(-rect.topLeft()); renderToPainter(&painter, rect); painter.end(); @@ -1597,7 +1599,7 @@ void SceneOpenGLDecorationRenderer::renderPart(const QRect &rect, const QRect &p // fill padding pixels by copying from the neighbour row clamp(image, padClip); - QPoint dirtyOffset = (rect.topLeft() - partRect.topLeft()) * devicePixelRatio(); + QPoint dirtyOffset = (rect.topLeft() - partRect.topLeft()) * devicePixelRatio; if (padding.top() == 0) { dirtyOffset.ry() += TexturePad; } @@ -1641,7 +1643,7 @@ void SceneOpenGLDecorationRenderer::resizeTexture() qMax(left.height(), right.height())); size.rheight() = top.height() + bottom.height() + left.width() + right.width(); - size *= devicePixelRatio(); + size *= effectiveDevicePixelRatio(); size.rheight() += 4 * (2 * TexturePad); size.rwidth() += 2 * TexturePad; diff --git a/src/scenes/opengl/scene_opengl.h b/src/scenes/opengl/scene_opengl.h index a43cdf39f1..1ae47c36dd 100644 --- a/src/scenes/opengl/scene_opengl.h +++ b/src/scenes/opengl/scene_opengl.h @@ -213,7 +213,7 @@ public: } private: - void renderPart(const QRect &rect, const QRect &partRect, const QPoint &textureOffset, bool rotated = false); + void renderPart(const QRect &rect, const QRect &partRect, const QPoint &textureOffset, qreal devicePixelRatio, bool rotated = false); static const QMargins texturePadForPart(const QRect &rect, const QRect &partRect); void resizeTexture(); QScopedPointer m_texture; diff --git a/src/scenes/qpainter/scene_qpainter.cpp b/src/scenes/qpainter/scene_qpainter.cpp index 2fcb0e814b..6f8d0e8df7 100644 --- a/src/scenes/qpainter/scene_qpainter.cpp +++ b/src/scenes/qpainter/scene_qpainter.cpp @@ -444,7 +444,7 @@ void SceneQPainterDecorationRenderer::render(const QRegion ®ion) } QPainter painter(&m_images[index]); painter.setRenderHint(QPainter::Antialiasing); - painter.setWindow(QRect(partRect.topLeft(), partRect.size() * qPainterEffectiveDevicePixelRatio(&painter))); + painter.setWindow(QRect(partRect.topLeft(), partRect.size() * effectiveDevicePixelRatio())); painter.setClipRect(rect); painter.save(); // clear existing part @@ -466,7 +466,7 @@ void SceneQPainterDecorationRenderer::resizeImages() client()->client()->layoutDecorationRects(left, top, right, bottom); auto checkAndCreate = [this](int index, const QSize &size) { - auto dpr = devicePixelRatio(); + auto dpr = effectiveDevicePixelRatio(); if (m_images[index].size() != size * dpr || m_images[index].devicePixelRatio() != dpr) { diff --git a/src/utils/common.cpp b/src/utils/common.cpp index 62be29a3ee..a5c7d19348 100644 --- a/src/utils/common.cpp +++ b/src/utils/common.cpp @@ -181,11 +181,6 @@ Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state) return ret; } -qreal qPainterEffectiveDevicePixelRatio(const QPainter *painter) -{ - return std::max(qreal(1), painter->device()->devicePixelRatioF()); -} - QPoint popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSize popupSize) { QPoint anchorPoint; diff --git a/src/utils/common.h b/src/utils/common.h index 196777f512..59f78b659b 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -123,15 +123,6 @@ void KWIN_EXPORT ungrabXServer(); bool KWIN_EXPORT grabXKeyboard(xcb_window_t w = XCB_WINDOW_NONE); void KWIN_EXPORT ungrabXKeyboard(); -/** - * QPainter::setWindow() doesn't work as expected when the device pixel ratio of the paint - * device is less than 1. - * - * QPainter simply doesn't allow the effective scale factor to be less than 1. Use this function - * to determine the effective device pixel ratio by which the window rect has to be scaled. - */ -qreal KWIN_EXPORT qPainterEffectiveDevicePixelRatio(const QPainter *painter); - static inline QRegion mapRegion(const QMatrix4x4 &matrix, const QRegion ®ion) { QRegion result;