Commit 23ef40e6 authored by Martin Flöser's avatar Martin Flöser

Move the X11 Decoration Renderer into the X11 standalone platform

Summary:
Not needed except for X11/non-composited usage, so should be in the
plugin instead of core.

Platform API is extended to create a decoration renderer.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7444
parent 535b1079
......@@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "composite.h"
#include "cursor.h"
#include "options.h"
#include "scene.h"
#include "platform.h"
#include "workspace.h"
#include <KDecoration2/DecoratedClient>
......@@ -290,11 +290,7 @@ bool DecoratedClientImpl::isApplicationMenuActive() const
void DecoratedClientImpl::createRenderer()
{
if (Compositor::self()->hasScene()) {
m_renderer = Compositor::self()->scene()->createDecorationRenderer(this);
} else {
m_renderer = new X11Renderer(this);
}
m_renderer = kwinApp()->platform()->createDecorationRenderer(this);
}
void DecoratedClientImpl::destroyRenderer()
......
......@@ -19,17 +19,13 @@ 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>
#include <KDecoration2/Decoration>
#include <KDecoration2/DecoratedClient>
#include <QDebug>
#include <QPainter>
#include <QTimer>
namespace KWin
{
......@@ -81,76 +77,5 @@ void Renderer::reparent(Deleted *deleted)
m_client = nullptr;
}
X11Renderer::X11Renderer(DecoratedClientImpl *client)
: Renderer(client)
, m_scheduleTimer(new QTimer(this))
, m_gc(XCB_NONE)
{
// delay any rendering to end of event cycle to catch multiple updates per cycle
m_scheduleTimer->setSingleShot(true);
m_scheduleTimer->setInterval(0);
connect(m_scheduleTimer, &QTimer::timeout, this, &X11Renderer::render);
connect(this, &Renderer::renderScheduled, m_scheduleTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
}
X11Renderer::~X11Renderer()
{
if (m_gc != XCB_NONE) {
xcb_free_gc(connection(), m_gc);
}
}
void X11Renderer::reparent(Deleted *deleted)
{
if (m_scheduleTimer->isActive()) {
m_scheduleTimer->stop();
}
disconnect(m_scheduleTimer, &QTimer::timeout, this, &X11Renderer::render);
disconnect(this, &Renderer::renderScheduled, m_scheduleTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
Renderer::reparent(deleted);
}
void X11Renderer::render()
{
if (!client()) {
return;
}
const QRegion scheduled = getScheduled();
if (scheduled.isEmpty()) {
return;
}
xcb_connection_t *c = connection();
if (m_gc == XCB_NONE) {
m_gc = xcb_generate_id(c);
xcb_create_gc(c, m_gc, client()->client()->frameId(), 0, nullptr);
}
QRect left, top, right, bottom;
client()->client()->layoutDecorationRects(left, top, right, bottom);
const QRect geometry = scheduled.boundingRect();
left = left.intersected(geometry);
top = top.intersected(geometry);
right = right.intersected(geometry);
bottom = bottom.intersected(geometry);
auto renderPart = [this, c](const QRect &geo) {
if (geo.isNull()) {
return;
}
QImage image = renderToImage(geo);
xcb_put_image(c, XCB_IMAGE_FORMAT_Z_PIXMAP, client()->client()->frameId(), m_gc,
image.width(), image.height(), geo.x(), geo.y(), 0, client()->client()->depth(),
image.byteCount(), image.constBits());
};
renderPart(left);
renderPart(top);
renderPart(right);
renderPart(bottom);
xcb_flush(c);
resetImageSizesDirty();
}
}
}
......@@ -23,12 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QObject>
#include <QRegion>
#include <xcb/xcb.h>
#include <kwin_export.h>
class QTimer;
namespace KWin
{
......@@ -84,23 +80,6 @@ private:
bool m_imageSizesDirty;
};
class X11Renderer : public Renderer
{
Q_OBJECT
public:
explicit X11Renderer(DecoratedClientImpl *client);
virtual ~X11Renderer();
void reparent(Deleted *deleted) override;
protected:
void render() override;
private:
QTimer *m_scheduleTimer;
xcb_gcontext_t m_gc;
};
}
}
......
......@@ -479,4 +479,12 @@ OutlineVisual *Platform::createOutline(Outline *outline)
return nullptr;
}
Decoration::Renderer *Platform::createDecorationRenderer(Decoration::DecoratedClientImpl *client)
{
if (Compositor::self()->hasScene()) {
Compositor::self()->scene()->createDecorationRenderer(client);
}
return nullptr;
}
}
......@@ -50,6 +50,12 @@ class ScreenEdges;
class Toplevel;
class WaylandCursorTheme;
namespace Decoration
{
class Renderer;
class DecoratedClientImpl;
}
class KWIN_EXPORT Platform : public QObject
{
Q_OBJECT
......@@ -325,6 +331,13 @@ public:
**/
virtual OutlineVisual *createOutline(Outline *outline);
/**
* Creates the Decoration::Renderer for the given @p client.
*
* The default implementation creates a Renderer suited for the Compositor, @c nullptr if there is no Compositor.
**/
virtual Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client);
public Q_SLOTS:
void pointerMotion(const QPointF &position, quint32 time);
void pointerButtonPressed(quint32 button, quint32 time);
......
......@@ -8,6 +8,7 @@ set(X11PLATFORM_SOURCES
overlaywindow_x11.cpp
screenedges_filter.cpp
non_composited_outline.cpp
x11_decoration_renderer.cpp
)
if(X11_Xinput_FOUND)
......
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "x11_decoration_renderer.h"
#include "decorations/decoratedclient.h"
#include "client.h"
#include "deleted.h"
#include <kwinglobals.h>
#include <KDecoration2/Decoration>
#include <KDecoration2/DecoratedClient>
#include <QTimer>
namespace KWin
{
namespace Decoration
{
X11Renderer::X11Renderer(DecoratedClientImpl *client)
: Renderer(client)
, m_scheduleTimer(new QTimer(this))
, m_gc(XCB_NONE)
{
// delay any rendering to end of event cycle to catch multiple updates per cycle
m_scheduleTimer->setSingleShot(true);
m_scheduleTimer->setInterval(0);
connect(m_scheduleTimer, &QTimer::timeout, this, &X11Renderer::render);
connect(this, &Renderer::renderScheduled, m_scheduleTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
}
X11Renderer::~X11Renderer()
{
if (m_gc != XCB_NONE) {
xcb_free_gc(connection(), m_gc);
}
}
void X11Renderer::reparent(Deleted *deleted)
{
if (m_scheduleTimer->isActive()) {
m_scheduleTimer->stop();
}
disconnect(m_scheduleTimer, &QTimer::timeout, this, &X11Renderer::render);
disconnect(this, &Renderer::renderScheduled, m_scheduleTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
Renderer::reparent(deleted);
}
void X11Renderer::render()
{
if (!client()) {
return;
}
const QRegion scheduled = getScheduled();
if (scheduled.isEmpty()) {
return;
}
xcb_connection_t *c = connection();
if (m_gc == XCB_NONE) {
m_gc = xcb_generate_id(c);
xcb_create_gc(c, m_gc, client()->client()->frameId(), 0, nullptr);
}
QRect left, top, right, bottom;
client()->client()->layoutDecorationRects(left, top, right, bottom);
const QRect geometry = scheduled.boundingRect();
left = left.intersected(geometry);
top = top.intersected(geometry);
right = right.intersected(geometry);
bottom = bottom.intersected(geometry);
auto renderPart = [this, c](const QRect &geo) {
if (geo.isNull()) {
return;
}
QImage image = renderToImage(geo);
xcb_put_image(c, XCB_IMAGE_FORMAT_Z_PIXMAP, client()->client()->frameId(), m_gc,
image.width(), image.height(), geo.x(), geo.y(), 0, client()->client()->depth(),
image.byteCount(), image.constBits());
};
renderPart(left);
renderPart(top);
renderPart(right);
renderPart(bottom);
xcb_flush(c);
resetImageSizesDirty();
}
}
}
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_DECORATION_X11_RENDERER_H
#define KWIN_DECORATION_X11_RENDERER_H
#include "decorations/decorationrenderer.h"
#include <xcb/xcb.h>
class QTimer;
namespace KWin
{
namespace Decoration
{
class X11Renderer : public Renderer
{
Q_OBJECT
public:
explicit X11Renderer(DecoratedClientImpl *client);
virtual ~X11Renderer();
void reparent(Deleted *deleted) override;
protected:
void render() override;
private:
QTimer *m_scheduleTimer;
xcb_gcontext_t m_gc;
};
}
}
#endif
......@@ -37,6 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "options.h"
#include "overlaywindow_x11.h"
#include "non_composited_outline.h"
#include "x11_decoration_renderer.h"
#include <KConfigGroup>
#include <KLocalizedString>
......@@ -346,4 +347,13 @@ OutlineVisual *X11StandalonePlatform::createOutline(Outline *outline)
return ret;
}
Decoration::Renderer *X11StandalonePlatform::createDecorationRenderer(Decoration::DecoratedClientImpl *client)
{
auto renderer = Platform::createDecorationRenderer(client);
if (!renderer) {
renderer = new Decoration::X11Renderer(client);
}
return renderer;
}
}
......@@ -60,6 +60,7 @@ public:
void updateXTime() override;
OutlineVisual *createOutline(Outline *outline) override;
Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client) override;
protected:
void doHideCursor() override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment