diff --git a/decorations/decorationrenderer.cpp b/decorations/decorationrenderer.cpp
index 7a451afacd..7280f67617 100644
--- a/decorations/decorationrenderer.cpp
+++ b/decorations/decorationrenderer.cpp
@@ -20,6 +20,7 @@ along with this program. If not, see .
#include "decorationrenderer.h"
#include "decoratedclient.h"
#include "client.h"
+#include "deleted.h"
#include
@@ -63,6 +64,7 @@ QRegion Renderer::getScheduled()
QImage Renderer::renderToImage(const QRect &geo)
{
+ Q_ASSERT(m_client);
QImage image(geo.width(), geo.height(), QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);
QPainter p(&image);
@@ -73,6 +75,12 @@ QImage Renderer::renderToImage(const QRect &geo)
return image;
}
+void Renderer::reparent(Deleted *deleted)
+{
+ setParent(deleted);
+ m_client = nullptr;
+}
+
X11Renderer::X11Renderer(DecoratedClientImpl *client)
: Renderer(client)
, m_scheduleTimer(new QTimer(this))
diff --git a/decorations/decorationrenderer.h b/decorations/decorationrenderer.h
index 8242a05095..4b842d71f8 100644
--- a/decorations/decorationrenderer.h
+++ b/decorations/decorationrenderer.h
@@ -30,6 +30,8 @@ class QTimer;
namespace KWin
{
+class Deleted;
+
namespace Decoration
{
@@ -43,6 +45,13 @@ public:
void schedule(const QRect &rect);
+ /**
+ * Reparents this Renderer to the @p deleted.
+ * After this call the Renderer is no longer able to render
+ * anything, client() returns a nullptr.
+ **/
+ virtual void reparent(Deleted *deleted);
+
Q_SIGNALS:
void renderScheduled(const QRect &geo);
diff --git a/deleted.cpp b/deleted.cpp
index a092ccb71e..4c349c9c20 100644
--- a/deleted.cpp
+++ b/deleted.cpp
@@ -24,6 +24,8 @@ along with this program. If not, see .
#include "client.h"
#include "netinfo.h"
#include "shadow.h"
+#include "decorations/decoratedclient.h"
+#include "decorations/decorationrenderer.h"
#include
@@ -35,14 +37,11 @@ Deleted::Deleted()
, delete_refcount(1)
, m_frame(XCB_WINDOW_NONE)
, no_border(true)
- , padding_left(0)
- , padding_top(0)
- , padding_right(0)
- , padding_bottom(0)
, m_layer(UnknownLayer)
, m_minimized(false)
, m_modal(false)
, m_wasClient(false)
+ , m_decorationRenderer(nullptr)
{
}
@@ -86,18 +85,18 @@ void Deleted::copyToDeleted(Toplevel* c)
if (client) {
m_wasClient = true;
no_border = client->noBorder();
-#if 0
- padding_left = client->paddingLeft();
- padding_right = client->paddingRight();
- padding_bottom = client->paddingBottom();
- padding_top = client->paddingTop();
-#endif
if (!no_border) {
client->layoutDecorationRects(decoration_left,
decoration_top,
decoration_right,
decoration_bottom,
Client::WindowRelative);
+ if (Decoration::DecoratedClientImpl *decoClient = client->decoratedClient()) {
+ if (Decoration::Renderer *renderer = decoClient->renderer()) {
+ m_decorationRenderer = renderer;
+ m_decorationRenderer->reparent(this);
+ }
+ }
}
m_minimized = client->isMinimized();
m_modal = client->isModal();
@@ -154,7 +153,7 @@ void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect
QRect Deleted::decorationRect() const
{
- return rect().adjusted(-padding_left, -padding_top, padding_top, padding_bottom);
+ return rect();
}
QRect Deleted::transparentRect() const
diff --git a/deleted.h b/deleted.h
index 79b631100e..0a667b1cc7 100644
--- a/deleted.h
+++ b/deleted.h
@@ -26,6 +26,11 @@ along with this program. If not, see .
namespace KWin
{
+namespace Decoration
+{
+class Renderer;
+}
+
class Deleted
: public Toplevel
{
@@ -66,6 +71,10 @@ public:
bool wasClient() const {
return m_wasClient;
}
+
+ const Decoration::Renderer *decorationRenderer() const {
+ return m_decorationRenderer;
+ }
protected:
virtual void debug(QDebug& stream) const;
virtual bool shouldUnredirect() const;
@@ -88,12 +97,12 @@ private:
QRect decoration_right;
QRect decoration_top;
QRect decoration_bottom;
- int padding_left, padding_top, padding_right, padding_bottom;
Layer m_layer;
bool m_minimized;
bool m_modal;
ClientList m_mainClients;
bool m_wasClient;
+ Decoration::Renderer *m_decorationRenderer;
};
inline void Deleted::refWindow()
diff --git a/scene_opengl.cpp b/scene_opengl.cpp
index 16fdcd8fce..bc5cd8a0eb 100644
--- a/scene_opengl.cpp
+++ b/scene_opengl.cpp
@@ -970,7 +970,6 @@ void SceneOpenGL::Window::endRenderWindow()
GLTexture *SceneOpenGL::Window::getDecorationTexture() const
{
- // TODO: deleted
if (toplevel->isClient()) {
Client *client = static_cast(toplevel);
if (client->noBorder()) {
@@ -983,6 +982,14 @@ GLTexture *SceneOpenGL::Window::getDecorationTexture() const
return renderer->texture();
}
}
+ } else if (toplevel->isDeleted()) {
+ Deleted *deleted = static_cast(toplevel);
+ if (!deleted->wasClient() || deleted->noBorder()) {
+ return nullptr;
+ }
+ if (const SceneOpenGLDecorationRenderer *renderer = static_cast(deleted->decorationRenderer())) {
+ return renderer->texture();
+ }
}
return nullptr;
}
@@ -2098,4 +2105,10 @@ void SceneOpenGLDecorationRenderer::resizeTexture()
}
}
+void SceneOpenGLDecorationRenderer::reparent(Deleted *deleted)
+{
+ render();
+ Renderer::reparent(deleted);
+}
+
} // namespace
diff --git a/scene_opengl.h b/scene_opengl.h
index d1b2a4fc64..b9347704c7 100644
--- a/scene_opengl.h
+++ b/scene_opengl.h
@@ -631,10 +631,14 @@ public:
virtual ~SceneOpenGLDecorationRenderer();
void render() override;
+ void reparent(Deleted *deleted) override;
GLTexture *texture() {
return m_texture.data();
}
+ GLTexture *texture() const {
+ return m_texture.data();
+ }
private:
void resizeTexture();
diff --git a/scene_qpainter.cpp b/scene_qpainter.cpp
index 493381cd8b..ec98c402fd 100644
--- a/scene_qpainter.cpp
+++ b/scene_qpainter.cpp
@@ -443,11 +443,12 @@ void SceneQPainter::Window::renderWindowDecorations(QPainter *painter)
}
bool noBorder = true;
- SceneQPainterDecorationRenderer *renderer = nullptr;
+ const SceneQPainterDecorationRenderer *renderer = nullptr;
QRect dtr, dlr, drr, dbr;
if (client && !client->noBorder()) {
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
if (SceneQPainterDecorationRenderer *r = static_cast(impl->renderer())) {
+ r->render();
renderer = r;
}
}
@@ -455,15 +456,13 @@ void SceneQPainter::Window::renderWindowDecorations(QPainter *painter)
noBorder = false;
} else if (deleted && !deleted->noBorder()) {
noBorder = false;
- // TODO: renderer
deleted->layoutDecorationRects(dlr, dtr, drr, dbr);
+ renderer = static_cast(deleted->decorationRenderer());
}
if (noBorder || !renderer) {
return;
}
- renderer->render();
-
painter->drawImage(dtr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Top));
painter->drawImage(dlr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Left));
painter->drawImage(drr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Right));
@@ -692,4 +691,10 @@ void SceneQPainterDecorationRenderer::resizeImages()
checkAndCreate(int(DecorationPart::Bottom), bottom.size());
}
+void SceneQPainterDecorationRenderer::reparent(Deleted *deleted)
+{
+ render();
+ Renderer::reparent(deleted);
+}
+
} // KWin
diff --git a/scene_qpainter.h b/scene_qpainter.h
index c5103667f5..7b59cfc4df 100644
--- a/scene_qpainter.h
+++ b/scene_qpainter.h
@@ -245,6 +245,7 @@ public:
virtual ~SceneQPainterDecorationRenderer();
void render() override;
+ void reparent(Deleted *deleted) override;
QImage image(DecorationPart part) const;
diff --git a/scene_xrender.cpp b/scene_xrender.cpp
index 2871cc3f3c..7df55ec878 100644
--- a/scene_xrender.cpp
+++ b/scene_xrender.cpp
@@ -722,19 +722,26 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat
xcb_render_picture_t right = XCB_RENDER_PICTURE_NONE;
xcb_render_picture_t bottom = XCB_RENDER_PICTURE_NONE;
QRect dtr, dlr, drr, dbr;
- SceneXRenderDecorationRenderer *renderer = nullptr;
- // TODO: deleted
+ const SceneXRenderDecorationRenderer *renderer = nullptr;
if (client) {
if (client && !client->noBorder()) {
if (Decoration::DecoratedClientImpl *impl = client->decoratedClient()) {
- renderer = static_cast(impl->renderer());
+ SceneXRenderDecorationRenderer *r = static_cast(impl->renderer());
+ if (r) {
+ r->render();
+ renderer = r;
+ }
}
noBorder = client->noBorder();
client->layoutDecorationRects(dlr, dtr, drr, dbr, Client::WindowRelative);
}
}
+ if (deleted && !deleted->noBorder()) {
+ renderer = static_cast(deleted->decorationRenderer());
+ noBorder = deleted->noBorder();
+ deleted->layoutDecorationRects(dlr, dtr, drr, dbr, Client::WindowRelative);
+ }
if (renderer) {
- renderer->render();
left = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Left);
top = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Top);
right = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Right);
@@ -1415,6 +1422,12 @@ xcb_render_picture_t SceneXRenderDecorationRenderer::picture(SceneXRenderDecorat
return *picture;
}
+void SceneXRenderDecorationRenderer::reparent(Deleted *deleted)
+{
+ render();
+ Renderer::reparent(deleted);
+}
+
#undef DOUBLE_TO_FIXED
#undef FIXED_TO_DOUBLE
diff --git a/scene_xrender.h b/scene_xrender.h
index fe0e5a1a0c..74472945ac 100644
--- a/scene_xrender.h
+++ b/scene_xrender.h
@@ -354,6 +354,7 @@ public:
virtual ~SceneXRenderDecorationRenderer();
void render() override;
+ void reparent(Deleted *deleted) override;
xcb_render_picture_t picture(DecorationPart part) const;