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