Kill Toplevel::screenScale()
Tracking AbstractOutput properties in Toplevel is not extensible. Since DecorationItem is the only one who needs Toplevel::screenScale(), make it track the output device pixel ratio.
This commit is contained in:
parent
1f318a2245
commit
cbad78a360
6 changed files with 57 additions and 41 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "decorationitem.h"
|
||||
#include "abstract_client.h"
|
||||
#include "abstract_output.h"
|
||||
#include "composite.h"
|
||||
#include "decorations/decoratedclient.h"
|
||||
#include "deleted.h"
|
||||
|
@ -28,8 +29,6 @@ DecorationRenderer::DecorationRenderer(Decoration::DecoratedClientImpl *client)
|
|||
connect(client->decoration(), &KDecoration2::Decoration::damaged,
|
||||
this, &DecorationRenderer::addDamage);
|
||||
|
||||
connect(client->client(), &AbstractClient::screenScaleChanged,
|
||||
this, &DecorationRenderer::invalidate);
|
||||
connect(client->decoration(), &KDecoration2::Decoration::bordersChanged,
|
||||
this, &DecorationRenderer::invalidate);
|
||||
connect(client->decoratedClient(), &KDecoration2::DecoratedClient::sizeChanged,
|
||||
|
@ -67,10 +66,22 @@ void DecorationRenderer::resetDamage()
|
|||
m_damage = QRegion();
|
||||
}
|
||||
|
||||
qreal DecorationRenderer::devicePixelRatio() const
|
||||
{
|
||||
return m_devicePixelRatio;
|
||||
}
|
||||
|
||||
void DecorationRenderer::setDevicePixelRatio(qreal dpr)
|
||||
{
|
||||
if (m_devicePixelRatio != dpr) {
|
||||
m_devicePixelRatio = dpr;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
QImage DecorationRenderer::renderToImage(const QRect &geo)
|
||||
{
|
||||
Q_ASSERT(m_client);
|
||||
auto dpr = client()->client()->screenScale();
|
||||
|
||||
// Guess the pixel format of the X pixmap into which the QImage will be copied.
|
||||
QImage::Format format;
|
||||
|
@ -89,8 +100,8 @@ QImage DecorationRenderer::renderToImage(const QRect &geo)
|
|||
break;
|
||||
};
|
||||
|
||||
QImage image(geo.width() * dpr, geo.height() * dpr, format);
|
||||
image.setDevicePixelRatio(dpr);
|
||||
QImage image(geo.width() * m_devicePixelRatio, geo.height() * m_devicePixelRatio, format);
|
||||
image.setDevicePixelRatio(m_devicePixelRatio);
|
||||
image.fill(Qt::transparent);
|
||||
QPainter p(&image);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
@ -115,9 +126,9 @@ DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, AbstractCli
|
|||
this, &DecorationItem::handleFrameGeometryChanged);
|
||||
connect(window, &Toplevel::windowClosed,
|
||||
this, &DecorationItem::handleWindowClosed);
|
||||
connect(window, &Toplevel::screenChanged,
|
||||
this, &DecorationItem::handleOutputChanged);
|
||||
|
||||
connect(window, &Toplevel::screenScaleChanged,
|
||||
this, &DecorationItem::discardQuads);
|
||||
connect(decoration, &KDecoration2::Decoration::bordersChanged,
|
||||
this, &DecorationItem::discardQuads);
|
||||
|
||||
|
@ -125,6 +136,7 @@ DecorationItem::DecorationItem(KDecoration2::Decoration *decoration, AbstractCli
|
|||
this, &DecorationItem::scheduleRepaint);
|
||||
|
||||
setSize(window->size());
|
||||
handleOutputChanged();
|
||||
}
|
||||
|
||||
void DecorationItem::preprocess()
|
||||
|
@ -136,6 +148,29 @@ void DecorationItem::preprocess()
|
|||
}
|
||||
}
|
||||
|
||||
void DecorationItem::handleOutputChanged()
|
||||
{
|
||||
if (m_output) {
|
||||
disconnect(m_output, &AbstractOutput::scaleChanged, this, &DecorationItem::handleOutputScaleChanged);
|
||||
}
|
||||
|
||||
m_output = m_window->output();
|
||||
|
||||
if (m_output) {
|
||||
handleOutputScaleChanged();
|
||||
connect(m_output, &AbstractOutput::scaleChanged, this, &DecorationItem::handleOutputScaleChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void DecorationItem::handleOutputScaleChanged()
|
||||
{
|
||||
const qreal dpr = m_output->scale();
|
||||
if (m_renderer->devicePixelRatio() != dpr) {
|
||||
m_renderer->setDevicePixelRatio(dpr);
|
||||
discardQuads();
|
||||
}
|
||||
}
|
||||
|
||||
void DecorationItem::handleFrameGeometryChanged()
|
||||
{
|
||||
setSize(m_window->size());
|
||||
|
@ -169,7 +204,7 @@ WindowQuadList DecorationItem::buildQuads() const
|
|||
deleted->layoutDecorationRects(rects[0], rects[1], rects[2], rects[3]);
|
||||
}
|
||||
|
||||
const qreal textureScale = m_window->screenScale();
|
||||
const qreal textureScale = m_renderer->devicePixelRatio();
|
||||
const int padding = 1;
|
||||
|
||||
const QPoint topSpritePosition(padding, padding);
|
||||
|
|
|
@ -38,6 +38,9 @@ public:
|
|||
void addDamage(const QRegion ®ion);
|
||||
void resetDamage();
|
||||
|
||||
qreal devicePixelRatio() const;
|
||||
void setDevicePixelRatio(qreal dpr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void damaged(const QRegion ®ion);
|
||||
|
||||
|
@ -58,6 +61,7 @@ protected:
|
|||
private:
|
||||
QPointer<Decoration::DecoratedClientImpl> m_client;
|
||||
QRegion m_damage;
|
||||
qreal m_devicePixelRatio = 1;
|
||||
bool m_imageSizesDirty;
|
||||
};
|
||||
|
||||
|
@ -76,6 +80,8 @@ public:
|
|||
private Q_SLOTS:
|
||||
void handleFrameGeometryChanged();
|
||||
void handleWindowClosed(Toplevel *original, Deleted *deleted);
|
||||
void handleOutputChanged();
|
||||
void handleOutputScaleChanged();
|
||||
|
||||
protected:
|
||||
void preprocess() override;
|
||||
|
@ -83,6 +89,7 @@ protected:
|
|||
|
||||
private:
|
||||
Toplevel *m_window;
|
||||
QPointer<AbstractOutput> m_output;
|
||||
QPointer<KDecoration2::Decoration> m_decoration;
|
||||
QScopedPointer<DecorationRenderer> m_renderer;
|
||||
};
|
||||
|
|
|
@ -1661,22 +1661,21 @@ void SceneOpenGLDecorationRenderer::render(const QRegion ®ion)
|
|||
}
|
||||
|
||||
QRect viewport = geo.translated(-rect.x(), -rect.y());
|
||||
const qreal devicePixelRatio = client()->client()->screenScale();
|
||||
|
||||
QImage image(rect.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
|
||||
image.setDevicePixelRatio(devicePixelRatio);
|
||||
QImage image(rect.size() * devicePixelRatio(), QImage::Format_ARGB32_Premultiplied);
|
||||
image.setDevicePixelRatio(devicePixelRatio());
|
||||
image.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setViewport(QRect(viewport.topLeft(), viewport.size() * devicePixelRatio));
|
||||
painter.setViewport(QRect(viewport.topLeft(), viewport.size() * devicePixelRatio()));
|
||||
painter.setWindow(QRect(geo.topLeft(), geo.size() * qPainterEffectiveDevicePixelRatio(&painter)));
|
||||
painter.setClipRect(geo);
|
||||
renderToPainter(&painter, geo);
|
||||
painter.end();
|
||||
|
||||
const QRect viewportScaled(viewport.topLeft() * devicePixelRatio, viewport.size() * devicePixelRatio);
|
||||
const bool isIntegerScaling = qFuzzyCompare(devicePixelRatio, std::ceil(devicePixelRatio));
|
||||
const QRect viewportScaled(viewport.topLeft() * devicePixelRatio(), viewport.size() * devicePixelRatio());
|
||||
const bool isIntegerScaling = qFuzzyCompare(devicePixelRatio(), std::ceil(devicePixelRatio()));
|
||||
clamp(image, isIntegerScaling ? viewportScaled : viewportScaled.marginsRemoved({1, 1, 1, 1}));
|
||||
|
||||
if (rotated) {
|
||||
|
@ -1725,7 +1724,7 @@ void SceneOpenGLDecorationRenderer::resizeTexture()
|
|||
|
||||
size.rwidth() = align(size.width(), 128);
|
||||
|
||||
size *= client()->client()->screenScale();
|
||||
size *= devicePixelRatio();
|
||||
if (m_texture && m_texture->size() == size)
|
||||
return;
|
||||
|
||||
|
|
|
@ -466,7 +466,7 @@ void SceneQPainterDecorationRenderer::resizeImages()
|
|||
client()->client()->layoutDecorationRects(left, top, right, bottom);
|
||||
|
||||
auto checkAndCreate = [this](int index, const QSize &size) {
|
||||
auto dpr = client()->client()->screenScale();
|
||||
auto dpr = devicePixelRatio();
|
||||
if (m_images[index].size() != size * dpr ||
|
||||
m_images[index].devicePixelRatio() != dpr)
|
||||
{
|
||||
|
|
|
@ -411,17 +411,6 @@ void Toplevel::setOutput(AbstractOutput *output)
|
|||
m_output = output;
|
||||
Q_EMIT screenChanged();
|
||||
}
|
||||
|
||||
qreal newScale = m_output->scale();
|
||||
if (newScale != m_screenScale) {
|
||||
m_screenScale = newScale;
|
||||
Q_EMIT screenScaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
qreal Toplevel::screenScale() const
|
||||
{
|
||||
return m_screenScale;
|
||||
}
|
||||
|
||||
bool Toplevel::isOnActiveOutput() const
|
||||
|
|
|
@ -344,12 +344,6 @@ public:
|
|||
int screen() const; // the screen where the center is
|
||||
AbstractOutput *output() const;
|
||||
void setOutput(AbstractOutput *output);
|
||||
/**
|
||||
* The scale of the screen this window is currently on
|
||||
* @note The buffer scale can be different.
|
||||
* @since 5.12
|
||||
*/
|
||||
qreal screenScale() const; //
|
||||
virtual QPoint clientPos() const = 0; // inside of geometry()
|
||||
QSize clientSize() const;
|
||||
/**
|
||||
|
@ -616,13 +610,6 @@ Q_SIGNALS:
|
|||
*/
|
||||
void surfaceChanged();
|
||||
|
||||
/*
|
||||
* Emitted when the client's screen changes onto a screen of a different scale
|
||||
* or the screen we're on changes
|
||||
* @since 5.12
|
||||
*/
|
||||
void screenScaleChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenever the client's shadow changes.
|
||||
* @since 5.15
|
||||
|
@ -717,7 +704,6 @@ private:
|
|||
quint32 m_pendingSurfaceId = 0;
|
||||
QPointer<KWaylandServer::SurfaceInterface> m_surface;
|
||||
// when adding new data members, check also copyToDeleted()
|
||||
qreal m_screenScale = 1.0;
|
||||
qreal m_opacity = 1.0;
|
||||
int m_stackingOrder = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue