From 23ef40e638095a6bcd1eb30dd0bb2756df83be3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Sun, 20 Aug 2017 22:15:21 +0200 Subject: [PATCH] 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 --- decorations/decoratedclient.cpp | 8 +- decorations/decorationrenderer.cpp | 75 ------------ decorations/decorationrenderer.h | 21 ---- platform.cpp | 8 ++ platform.h | 13 +++ .../platforms/x11/standalone/CMakeLists.txt | 1 + .../standalone/x11_decoration_renderer.cpp | 109 ++++++++++++++++++ .../x11/standalone/x11_decoration_renderer.h | 55 +++++++++ .../platforms/x11/standalone/x11_platform.cpp | 10 ++ .../platforms/x11/standalone/x11_platform.h | 1 + 10 files changed, 199 insertions(+), 102 deletions(-) create mode 100644 plugins/platforms/x11/standalone/x11_decoration_renderer.cpp create mode 100644 plugins/platforms/x11/standalone/x11_decoration_renderer.h diff --git a/decorations/decoratedclient.cpp b/decorations/decoratedclient.cpp index 8ba6c6c9a9..ff5ce64d4e 100644 --- a/decorations/decoratedclient.cpp +++ b/decorations/decoratedclient.cpp @@ -24,7 +24,7 @@ along with this program. If not, see . #include "composite.h" #include "cursor.h" #include "options.h" -#include "scene.h" +#include "platform.h" #include "workspace.h" #include @@ -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() diff --git a/decorations/decorationrenderer.cpp b/decorations/decorationrenderer.cpp index 5c281e634d..420c2476cc 100644 --- a/decorations/decorationrenderer.cpp +++ b/decorations/decorationrenderer.cpp @@ -19,17 +19,13 @@ along with this program. If not, see . *********************************************************************/ #include "decorationrenderer.h" #include "decoratedclient.h" -#include "client.h" #include "deleted.h" -#include - #include #include #include #include -#include 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(&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(&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(); -} - } } diff --git a/decorations/decorationrenderer.h b/decorations/decorationrenderer.h index 17d184bda9..417bf849fb 100644 --- a/decorations/decorationrenderer.h +++ b/decorations/decorationrenderer.h @@ -23,12 +23,8 @@ along with this program. If not, see . #include #include -#include - #include -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; -}; - } } diff --git a/platform.cpp b/platform.cpp index d9ac032063..8400d4b090 100644 --- a/platform.cpp +++ b/platform.cpp @@ -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; +} + } diff --git a/platform.h b/platform.h index 80b5072a13..5c55480c5d 100644 --- a/platform.h +++ b/platform.h @@ -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); diff --git a/plugins/platforms/x11/standalone/CMakeLists.txt b/plugins/platforms/x11/standalone/CMakeLists.txt index 1f398bc6f5..20bab3f5aa 100644 --- a/plugins/platforms/x11/standalone/CMakeLists.txt +++ b/plugins/platforms/x11/standalone/CMakeLists.txt @@ -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) diff --git a/plugins/platforms/x11/standalone/x11_decoration_renderer.cpp b/plugins/platforms/x11/standalone/x11_decoration_renderer.cpp new file mode 100644 index 0000000000..d8b49544a6 --- /dev/null +++ b/plugins/platforms/x11/standalone/x11_decoration_renderer.cpp @@ -0,0 +1,109 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2014 Martin Gräßlin + +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 . +*********************************************************************/ +#include "x11_decoration_renderer.h" +#include "decorations/decoratedclient.h" +#include "client.h" +#include "deleted.h" + +#include + +#include +#include + +#include + +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(&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(&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(); +} + +} +} diff --git a/plugins/platforms/x11/standalone/x11_decoration_renderer.h b/plugins/platforms/x11/standalone/x11_decoration_renderer.h new file mode 100644 index 0000000000..bbcda97280 --- /dev/null +++ b/plugins/platforms/x11/standalone/x11_decoration_renderer.h @@ -0,0 +1,55 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2014 Martin Gräßlin + +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 . +*********************************************************************/ +#ifndef KWIN_DECORATION_X11_RENDERER_H +#define KWIN_DECORATION_X11_RENDERER_H + +#include "decorations/decorationrenderer.h" + +#include + +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 diff --git a/plugins/platforms/x11/standalone/x11_platform.cpp b/plugins/platforms/x11/standalone/x11_platform.cpp index 59bd8dd90f..34cb91cd13 100644 --- a/plugins/platforms/x11/standalone/x11_platform.cpp +++ b/plugins/platforms/x11/standalone/x11_platform.cpp @@ -37,6 +37,7 @@ along with this program. If not, see . #include "options.h" #include "overlaywindow_x11.h" #include "non_composited_outline.h" +#include "x11_decoration_renderer.h" #include #include @@ -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; +} + } diff --git a/plugins/platforms/x11/standalone/x11_platform.h b/plugins/platforms/x11/standalone/x11_platform.h index 9fce72a0a5..6f0022ffe5 100644 --- a/plugins/platforms/x11/standalone/x11_platform.h +++ b/plugins/platforms/x11/standalone/x11_platform.h @@ -60,6 +60,7 @@ public: void updateXTime() override; OutlineVisual *createOutline(Outline *outline) override; + Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client) override; protected: void doHideCursor() override;