Pass Decoration::Renderer to Deleted and use it in the Scenes
The Renderer gets reparented to the Deleted. While passing it to the Deleted the Scene's implementation can ensure that the buffers are up to date. After passing to Deleted it's no longer allowed to call the render method.
This commit is contained in:
parent
a9587dd19d
commit
c12199a8e0
10 changed files with 83 additions and 21 deletions
|
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "decorationrenderer.h"
|
||||
#include "decoratedclient.h"
|
||||
#include "client.h"
|
||||
#include "deleted.h"
|
||||
|
||||
#include <kwinglobals.h>
|
||||
|
||||
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
21
deleted.cpp
21
deleted.cpp
|
@ -24,6 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "client.h"
|
||||
#include "netinfo.h"
|
||||
#include "shadow.h"
|
||||
#include "decorations/decoratedclient.h"
|
||||
#include "decorations/decorationrenderer.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -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
|
||||
|
|
11
deleted.h
11
deleted.h
|
@ -26,6 +26,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
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()
|
||||
|
|
|
@ -970,7 +970,6 @@ void SceneOpenGL::Window::endRenderWindow()
|
|||
|
||||
GLTexture *SceneOpenGL::Window::getDecorationTexture() const
|
||||
{
|
||||
// TODO: deleted
|
||||
if (toplevel->isClient()) {
|
||||
Client *client = static_cast<Client *>(toplevel);
|
||||
if (client->noBorder()) {
|
||||
|
@ -983,6 +982,14 @@ GLTexture *SceneOpenGL::Window::getDecorationTexture() const
|
|||
return renderer->texture();
|
||||
}
|
||||
}
|
||||
} else if (toplevel->isDeleted()) {
|
||||
Deleted *deleted = static_cast<Deleted *>(toplevel);
|
||||
if (!deleted->wasClient() || deleted->noBorder()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (const SceneOpenGLDecorationRenderer *renderer = static_cast<const SceneOpenGLDecorationRenderer*>(deleted->decorationRenderer())) {
|
||||
return renderer->texture();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2098,4 +2105,10 @@ void SceneOpenGLDecorationRenderer::resizeTexture()
|
|||
}
|
||||
}
|
||||
|
||||
void SceneOpenGLDecorationRenderer::reparent(Deleted *deleted)
|
||||
{
|
||||
render();
|
||||
Renderer::reparent(deleted);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<SceneQPainterDecorationRenderer *>(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<const SceneQPainterDecorationRenderer *>(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
|
||||
|
|
|
@ -245,6 +245,7 @@ public:
|
|||
virtual ~SceneQPainterDecorationRenderer();
|
||||
|
||||
void render() override;
|
||||
void reparent(Deleted *deleted) override;
|
||||
|
||||
QImage image(DecorationPart part) const;
|
||||
|
||||
|
|
|
@ -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<SceneXRenderDecorationRenderer*>(impl->renderer());
|
||||
SceneXRenderDecorationRenderer *r = static_cast<SceneXRenderDecorationRenderer*>(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<const SceneXRenderDecorationRenderer*>(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
|
||||
|
||||
|
|
|
@ -354,6 +354,7 @@ public:
|
|||
virtual ~SceneXRenderDecorationRenderer();
|
||||
|
||||
void render() override;
|
||||
void reparent(Deleted *deleted) override;
|
||||
|
||||
xcb_render_picture_t picture(DecorationPart part) const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue