decoration: Fix rendering issues with scale factors < 1

QPainter::setWindow() doesn't work as we expect if the device pixel
ratio of the paint device is less than 1, for example 0.5 or 0.75.

QPainter only allows the effective device pixel ratios that are greater
than or equal to 1. This restriction probably has to be lifted.

For the time being, this change introduces a helper function that can be
used to determine the scale factor by which QPainter::window() must be
multiplied.

BUG: 432766
master
Vlad Zahorodnii 4 years ago
parent 385ea10bef
commit c9ac2e3fb8

@ -80,7 +80,7 @@ QImage Renderer::renderToImage(const QRect &geo)
image.fill(Qt::transparent);
QPainter p(&image);
p.setRenderHint(QPainter::Antialiasing);
p.setWindow(QRect(geo.topLeft(), geo.size() * dpr));
p.setWindow(QRect(geo.topLeft(), geo.size() * qPainterEffectiveDevicePixelRatio(&p)));
p.setClipRect(geo);
renderToPainter(&p, geo);
return image;

@ -2644,7 +2644,7 @@ void SceneOpenGLDecorationRenderer::render()
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing);
painter.setViewport(QRect(viewport.topLeft(), viewport.size() * devicePixelRatio));
painter.setWindow(QRect(geo.topLeft(), geo.size() * devicePixelRatio));
painter.setWindow(QRect(geo.topLeft(), geo.size() * qPainterEffectiveDevicePixelRatio(&painter)));
painter.setClipRect(geo);
renderToPainter(&painter, geo);
painter.end();

@ -774,7 +774,7 @@ void SceneQPainterDecorationRenderer::render()
}
QPainter painter(&m_images[index]);
painter.setRenderHint(QPainter::Antialiasing);
painter.setWindow(QRect(partRect.topLeft(), partRect.size() * m_images[index].devicePixelRatio()));
painter.setWindow(QRect(partRect.topLeft(), partRect.size() * qPainterEffectiveDevicePixelRatio(&painter)));
painter.setClipRect(rect);
painter.save();
// clear existing part

@ -16,6 +16,7 @@
#include "utils.h"
#include <QPainter>
#include <QWidget>
#include <kkeyserver.h>
@ -195,6 +196,11 @@ Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state)
return ret;
}
qreal qPainterEffectiveDevicePixelRatio(const QPainter *painter)
{
return std::max(qreal(1), painter->device()->devicePixelRatioF());
}
} // namespace
#ifndef KCMRULES

@ -119,6 +119,15 @@ 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);
/**
* Small helper class which performs grabXServer in the ctor and
* ungrabXServer in the dtor. Use this class to ensure that grab and

Loading…
Cancel
Save