diff --git a/plugins/scenes/qpainter/scene_qpainter.cpp b/plugins/scenes/qpainter/scene_qpainter.cpp
index ed8a9d32d8..98dca03e34 100644
--- a/plugins/scenes/qpainter/scene_qpainter.cpp
+++ b/plugins/scenes/qpainter/scene_qpainter.cpp
@@ -19,7 +19,7 @@ along with this program. If not, see .
*********************************************************************/
#include "scene_qpainter.h"
// KWin
-#include "x11client.h"
+#include "abstract_client.h"
#include "composite.h"
#include "cursor.h"
#include "deleted.h"
@@ -228,37 +228,6 @@ SceneQPainter::Window::~Window()
{
}
-static void paintSubSurface(QPainter *painter, const QPoint &pos, QPainterWindowPixmap *pixmap)
-{
- QPoint p = pos;
- if (!pixmap->subSurface().isNull()) {
- p += pixmap->subSurface()->position();
- }
-
- painter->drawImage(QRect(pos, pixmap->size()), pixmap->image());
- const auto &children = pixmap->children();
- for (auto it = children.begin(); it != children.end(); ++it) {
- auto pixmap = static_cast(*it);
- if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) {
- continue;
- }
- paintSubSurface(painter, p, pixmap);
- }
-}
-
-static bool isXwaylandClient(Toplevel *toplevel)
-{
- X11Client *client = qobject_cast(toplevel);
- if (client) {
- return true;
- }
- Deleted *deleted = qobject_cast(toplevel);
- if (deleted) {
- return deleted->wasX11Client();
- }
- return false;
-}
-
void SceneQPainter::Window::performPaint(int mask, const QRegion &_region, const WindowPaintData &data)
{
QRegion region = _region;
@@ -299,28 +268,7 @@ void SceneQPainter::Window::performPaint(int mask, const QRegion &_region, const
}
renderShadow(painter);
renderWindowDecorations(painter);
-
- // render content
- QRect source;
- QRect target;
- if (isXwaylandClient(toplevel)) {
- // special case for XWayland windows
- source = QRect(toplevel->clientPos(), toplevel->clientSize());
- target = source;
- } else {
- source = pixmap->image().rect();
- target = toplevel->bufferGeometry().translated(-pos());
- }
- painter->drawImage(target, pixmap->image(), source);
-
- // render subsurfaces
- const auto &children = pixmap->children();
- for (auto pixmap : children) {
- if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) {
- continue;
- }
- paintSubSurface(painter, bufferOffset(), static_cast(pixmap));
- }
+ renderWindowPixmap(painter, pixmap);
if (!opaque) {
tempPainter.restore();
@@ -336,6 +284,30 @@ void SceneQPainter::Window::performPaint(int mask, const QRegion &_region, const
painter->restore();
}
+void SceneQPainter::Window::renderWindowPixmap(QPainter *painter, QPainterWindowPixmap *windowPixmap)
+{
+ const QRegion shape = windowPixmap->shape();
+ for (const QRectF &rect : shape) {
+ const QPointF windowTopLeft = windowPixmap->mapToWindow(rect.topLeft());
+ const QPointF windowBottomRight = windowPixmap->mapToWindow(rect.bottomRight());
+
+ const QPointF bufferTopLeft = windowPixmap->mapToBuffer(rect.topLeft());
+ const QPointF bufferBottomRight = windowPixmap->mapToBuffer(rect.bottomRight());
+
+ painter->drawImage(QRectF(windowTopLeft, windowBottomRight),
+ windowPixmap->image(),
+ QRectF(bufferTopLeft, bufferBottomRight));
+ }
+
+ const QVector children = windowPixmap->children();
+ for (WindowPixmap *child : children) {
+ QPainterWindowPixmap *scenePixmap = static_cast(child);
+ if (scenePixmap->isValid()) {
+ renderWindowPixmap(painter, scenePixmap);
+ }
+ }
+}
+
void SceneQPainter::Window::renderShadow(QPainter* painter)
{
if (!toplevel->shadow()) {
diff --git a/plugins/scenes/qpainter/scene_qpainter.h b/plugins/scenes/qpainter/scene_qpainter.h
index 88354e505c..18400162d4 100644
--- a/plugins/scenes/qpainter/scene_qpainter.h
+++ b/plugins/scenes/qpainter/scene_qpainter.h
@@ -71,20 +71,6 @@ private:
class Window;
};
-class SceneQPainter::Window : public Scene::Window
-{
-public:
- Window(SceneQPainter *scene, Toplevel *c);
- ~Window() override;
- void performPaint(int mask, const QRegion ®ion, const WindowPaintData &data) override;
-protected:
- WindowPixmap *createWindowPixmap() override;
-private:
- void renderShadow(QPainter *painter);
- void renderWindowDecorations(QPainter *painter);
- SceneQPainter *m_scene;
-};
-
class QPainterWindowPixmap : public WindowPixmap
{
public:
@@ -103,6 +89,21 @@ private:
QImage m_image;
};
+class SceneQPainter::Window : public Scene::Window
+{
+public:
+ Window(SceneQPainter *scene, Toplevel *c);
+ ~Window() override;
+ void performPaint(int mask, const QRegion ®ion, const WindowPaintData &data) override;
+protected:
+ WindowPixmap *createWindowPixmap() override;
+private:
+ void renderWindowPixmap(QPainter *painter, QPainterWindowPixmap *windowPixmap);
+ void renderShadow(QPainter *painter);
+ void renderWindowDecorations(QPainter *painter);
+ SceneQPainter *m_scene;
+};
+
class QPainterEffectFrame : public Scene::EffectFrame
{
public:
diff --git a/scene.cpp b/scene.cpp
index d798998092..4ae814e209 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -1028,30 +1028,28 @@ WindowQuadList Scene::Window::makeContentsQuads() const
continue;
const QRegion region = windowPixmap->shape();
- const QPoint position = windowPixmap->framePosition();
- const qreal scale = windowPixmap->scale();
const int quadId = id++;
- for (const QRect &rect : region) {
+ for (const QRectF &rect : region) {
// Note that the window quad id is not unique if the window is shaped, i.e. the
// region contains more than just one rectangle. We assume that the "source" quad
// had been subdivided.
WindowQuad quad(WindowQuadContents, quadId);
- const qreal x0 = rect.x() + position.x();
- const qreal y0 = rect.y() + position.y();
- const qreal x1 = rect.x() + rect.width() + position.x();
- const qreal y1 = rect.y() + rect.height() + position.y();
+ const QPointF windowTopLeft = windowPixmap->mapToWindow(rect.topLeft());
+ const QPointF windowTopRight = windowPixmap->mapToWindow(rect.topRight());
+ const QPointF windowBottomRight = windowPixmap->mapToWindow(rect.bottomRight());
+ const QPointF windowBottomLeft = windowPixmap->mapToWindow(rect.bottomLeft());
- const qreal u0 = rect.x() * scale;
- const qreal v0 = rect.y() * scale;
- const qreal u1 = (rect.x() + rect.width()) * scale;
- const qreal v1 = (rect.y() + rect.height()) * scale;
+ const QPointF bufferTopLeft = windowPixmap->mapToBuffer(rect.topLeft());
+ const QPointF bufferTopRight = windowPixmap->mapToBuffer(rect.topRight());
+ const QPointF bufferBottomRight = windowPixmap->mapToBuffer(rect.bottomRight());
+ const QPointF bufferBottomLeft = windowPixmap->mapToBuffer(rect.bottomLeft());
- quad[0] = WindowVertex(QPointF(x0, y0), QPointF(u0, v0));
- quad[1] = WindowVertex(QPointF(x1, y0), QPointF(u1, v0));
- quad[2] = WindowVertex(QPointF(x1, y1), QPointF(u1, v1));
- quad[3] = WindowVertex(QPointF(x0, y1), QPointF(u0, v1));
+ quad[0] = WindowVertex(windowTopLeft, bufferTopLeft);
+ quad[1] = WindowVertex(windowTopRight, bufferTopRight);
+ quad[2] = WindowVertex(windowBottomRight, bufferBottomRight);
+ quad[3] = WindowVertex(windowBottomLeft, bufferBottomLeft);
quads << quad;
}
@@ -1288,6 +1286,16 @@ bool WindowPixmap::hasAlphaChannel() const
return toplevel()->hasAlpha();
}
+QPointF WindowPixmap::mapToWindow(const QPointF &point) const
+{
+ return point + framePosition();
+}
+
+QPointF WindowPixmap::mapToBuffer(const QPointF &point) const
+{
+ return point * scale();
+}
+
//****************************************
// Scene::EffectFrame
//****************************************
diff --git a/scene.h b/scene.h
index fdeb10e304..e9a9171ee5 100644
--- a/scene.h
+++ b/scene.h
@@ -502,6 +502,14 @@ public:
* Returns @c true if the attached buffer has an alpha channel; otherwise returns @c false.
*/
bool hasAlphaChannel() const;
+ /**
+ * Maps the specified @a point from the window pixmap coordinates to the window local coordinates.
+ */
+ QPointF mapToWindow(const QPointF &point) const;
+ /**
+ * Maps the specified @a point from the window pixmap coordinates to the buffer pixel coordinates.
+ */
+ QPointF mapToBuffer(const QPointF &point) const;
/**
* @returns the parent WindowPixmap in the sub-surface tree