Changeset View
Changeset View
Standalone View
Standalone View
decorations/decorationrenderer.cpp
- This file was copied to plugins/platforms/x11/standalone/x11_decoration_renderer.cpp.
Show All 13 Lines | |||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #include "decorationrenderer.h" | 20 | #include "decorationrenderer.h" | ||
21 | #include "decoratedclient.h" | 21 | #include "decoratedclient.h" | ||
22 | #include "client.h" | | |||
23 | #include "deleted.h" | 22 | #include "deleted.h" | ||
24 | 23 | | |||
25 | #include <kwinglobals.h> | | |||
26 | | ||||
27 | #include <KDecoration2/Decoration> | 24 | #include <KDecoration2/Decoration> | ||
28 | #include <KDecoration2/DecoratedClient> | 25 | #include <KDecoration2/DecoratedClient> | ||
29 | 26 | | |||
30 | #include <QDebug> | 27 | #include <QDebug> | ||
31 | #include <QPainter> | 28 | #include <QPainter> | ||
32 | #include <QTimer> | | |||
33 | 29 | | |||
34 | namespace KWin | 30 | namespace KWin | ||
35 | { | 31 | { | ||
36 | namespace Decoration | 32 | namespace Decoration | ||
37 | { | 33 | { | ||
38 | 34 | | |||
39 | Renderer::Renderer(DecoratedClientImpl *client) | 35 | Renderer::Renderer(DecoratedClientImpl *client) | ||
40 | : QObject(client) | 36 | : QObject(client) | ||
Show All 35 Lines | |||||
76 | } | 72 | } | ||
77 | 73 | | |||
78 | void Renderer::reparent(Deleted *deleted) | 74 | void Renderer::reparent(Deleted *deleted) | ||
79 | { | 75 | { | ||
80 | setParent(deleted); | 76 | setParent(deleted); | ||
81 | m_client = nullptr; | 77 | m_client = nullptr; | ||
82 | } | 78 | } | ||
83 | 79 | | |||
84 | X11Renderer::X11Renderer(DecoratedClientImpl *client) | | |||
85 | : Renderer(client) | | |||
86 | , m_scheduleTimer(new QTimer(this)) | | |||
87 | , m_gc(XCB_NONE) | | |||
88 | { | | |||
89 | // delay any rendering to end of event cycle to catch multiple updates per cycle | | |||
90 | m_scheduleTimer->setSingleShot(true); | | |||
91 | m_scheduleTimer->setInterval(0); | | |||
92 | connect(m_scheduleTimer, &QTimer::timeout, this, &X11Renderer::render); | | |||
93 | connect(this, &Renderer::renderScheduled, m_scheduleTimer, static_cast<void (QTimer::*)()>(&QTimer::start)); | | |||
94 | } | | |||
95 | | ||||
96 | X11Renderer::~X11Renderer() | | |||
97 | { | | |||
98 | if (m_gc != XCB_NONE) { | | |||
99 | xcb_free_gc(connection(), m_gc); | | |||
100 | } | | |||
101 | } | | |||
102 | | ||||
103 | void X11Renderer::reparent(Deleted *deleted) | | |||
104 | { | | |||
105 | if (m_scheduleTimer->isActive()) { | | |||
106 | m_scheduleTimer->stop(); | | |||
107 | } | | |||
108 | disconnect(m_scheduleTimer, &QTimer::timeout, this, &X11Renderer::render); | | |||
109 | disconnect(this, &Renderer::renderScheduled, m_scheduleTimer, static_cast<void (QTimer::*)()>(&QTimer::start)); | | |||
110 | Renderer::reparent(deleted); | | |||
111 | } | | |||
112 | | ||||
113 | void X11Renderer::render() | | |||
114 | { | | |||
115 | if (!client()) { | | |||
116 | return; | | |||
117 | } | | |||
118 | const QRegion scheduled = getScheduled(); | | |||
119 | if (scheduled.isEmpty()) { | | |||
120 | return; | | |||
121 | } | | |||
122 | xcb_connection_t *c = connection(); | | |||
123 | if (m_gc == XCB_NONE) { | | |||
124 | m_gc = xcb_generate_id(c); | | |||
125 | xcb_create_gc(c, m_gc, client()->client()->frameId(), 0, nullptr); | | |||
126 | } | | |||
127 | | ||||
128 | QRect left, top, right, bottom; | | |||
129 | client()->client()->layoutDecorationRects(left, top, right, bottom); | | |||
130 | | ||||
131 | const QRect geometry = scheduled.boundingRect(); | | |||
132 | left = left.intersected(geometry); | | |||
133 | top = top.intersected(geometry); | | |||
134 | right = right.intersected(geometry); | | |||
135 | bottom = bottom.intersected(geometry); | | |||
136 | | ||||
137 | auto renderPart = [this, c](const QRect &geo) { | | |||
138 | if (geo.isNull()) { | | |||
139 | return; | | |||
140 | } | | |||
141 | QImage image = renderToImage(geo); | | |||
142 | xcb_put_image(c, XCB_IMAGE_FORMAT_Z_PIXMAP, client()->client()->frameId(), m_gc, | | |||
143 | image.width(), image.height(), geo.x(), geo.y(), 0, client()->client()->depth(), | | |||
144 | image.byteCount(), image.constBits()); | | |||
145 | }; | | |||
146 | renderPart(left); | | |||
147 | renderPart(top); | | |||
148 | renderPart(right); | | |||
149 | renderPart(bottom); | | |||
150 | | ||||
151 | xcb_flush(c); | | |||
152 | resetImageSizesDirty(); | | |||
153 | } | | |||
154 | | ||||
155 | } | 80 | } | ||
156 | } | 81 | } |