1/*
2 SPDX-FileCopyrightText: 2018 David Edmundson <kde@davidedmundson.co.uk>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#include "xdgdecoration.h"
7
8#include "event_queue.h"
9#include "wayland_pointer_p.h"
10#include "xdgshell.h"
11
12#include <QDebug>
13
14#include "wayland-xdg-decoration-unstable-v1-client-protocol.h"
15
16namespace KWayland
17{
18namespace Client
19{
20class Q_DECL_HIDDEN XdgDecorationManager::Private
21{
22public:
23 Private() = default;
24
25 void setup(zxdg_decoration_manager_v1 *arg);
26
27 WaylandPointer<zxdg_decoration_manager_v1, zxdg_decoration_manager_v1_destroy> xdgdecorationmanager;
28 EventQueue *queue = nullptr;
29};
30
31XdgDecorationManager::XdgDecorationManager(QObject *parent)
32 : QObject(parent)
33 , d(new Private)
34{
35}
36
37void XdgDecorationManager::Private::setup(zxdg_decoration_manager_v1 *arg)
38{
39 Q_ASSERT(arg);
40 Q_ASSERT(!xdgdecorationmanager);
41 xdgdecorationmanager.setup(pointer: arg);
42}
43
44XdgDecorationManager::~XdgDecorationManager()
45{
46 release();
47}
48
49void XdgDecorationManager::setup(zxdg_decoration_manager_v1 *xdgdecorationmanager)
50{
51 d->setup(xdgdecorationmanager);
52}
53
54void XdgDecorationManager::release()
55{
56 d->xdgdecorationmanager.release();
57}
58
59void XdgDecorationManager::destroy()
60{
61 d->xdgdecorationmanager.destroy();
62}
63
64XdgDecorationManager::operator zxdg_decoration_manager_v1 *()
65{
66 return d->xdgdecorationmanager;
67}
68
69XdgDecorationManager::operator zxdg_decoration_manager_v1 *() const
70{
71 return d->xdgdecorationmanager;
72}
73
74bool XdgDecorationManager::isValid() const
75{
76 return d->xdgdecorationmanager.isValid();
77}
78
79void XdgDecorationManager::setEventQueue(EventQueue *queue)
80{
81 d->queue = queue;
82}
83
84EventQueue *XdgDecorationManager::eventQueue()
85{
86 return d->queue;
87}
88
89XdgDecoration *XdgDecorationManager::getToplevelDecoration(XdgShellSurface *toplevel, QObject *parent)
90{
91 Q_ASSERT(isValid());
92 xdg_toplevel *toplevel_resource = *toplevel;
93 if (!toplevel_resource) { // i.e using XDGShellV5
94 qWarning() << "Trying to create an XdgDecoration without an XDGShell stable toplevel object";
95 return nullptr;
96 }
97 auto p = new XdgDecoration(parent);
98 auto w = zxdg_decoration_manager_v1_get_toplevel_decoration(zxdg_decoration_manager_v1: d->xdgdecorationmanager, toplevel: toplevel_resource);
99 if (d->queue) {
100 d->queue->addProxy(proxy: w);
101 }
102 p->setup(w);
103 return p;
104}
105
106class Q_DECL_HIDDEN XdgDecoration::Private
107{
108public:
109 Private(XdgDecoration *q);
110
111 void setup(zxdg_toplevel_decoration_v1 *arg);
112
113 WaylandPointer<zxdg_toplevel_decoration_v1, zxdg_toplevel_decoration_v1_destroy> xdgdecoration;
114
115 XdgDecoration::Mode m_mode = XdgDecoration::Mode::ClientSide;
116
117private:
118 XdgDecoration *q;
119
120private:
121 static void configureCallback(void *data, zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode);
122
123 static const zxdg_toplevel_decoration_v1_listener s_listener;
124};
125
126const zxdg_toplevel_decoration_v1_listener XdgDecoration::Private::s_listener = {.configure: configureCallback};
127
128void XdgDecoration::Private::configureCallback(void *data, zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t m)
129{
130 auto p = reinterpret_cast<XdgDecoration::Private *>(data);
131 Q_ASSERT(p->xdgdecoration == zxdg_toplevel_decoration_v1);
132 switch (m) {
133 case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
134 p->m_mode = XdgDecoration::Mode::ClientSide;
135 break;
136 case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
137 p->m_mode = XdgDecoration::Mode::ServerSide;
138 break;
139 }
140 Q_EMIT p->q->modeChanged(mode: p->m_mode);
141}
142
143XdgDecoration::Private::Private(XdgDecoration *q)
144 : q(q)
145{
146}
147
148XdgDecoration::XdgDecoration(QObject *parent)
149 : QObject(parent)
150 , d(new Private(this))
151{
152}
153
154void XdgDecoration::Private::setup(zxdg_toplevel_decoration_v1 *arg)
155{
156 Q_ASSERT(arg);
157 Q_ASSERT(!xdgdecoration);
158 xdgdecoration.setup(pointer: arg);
159 zxdg_toplevel_decoration_v1_add_listener(zxdg_toplevel_decoration_v1: xdgdecoration, listener: &s_listener, data: this);
160}
161
162XdgDecoration::~XdgDecoration()
163{
164 release();
165}
166
167void XdgDecoration::setup(zxdg_toplevel_decoration_v1 *xdgdecoration)
168{
169 d->setup(xdgdecoration);
170}
171
172void XdgDecoration::release()
173{
174 d->xdgdecoration.release();
175}
176
177void XdgDecoration::destroy()
178{
179 d->xdgdecoration.destroy();
180}
181
182XdgDecoration::operator zxdg_toplevel_decoration_v1 *()
183{
184 return d->xdgdecoration;
185}
186
187XdgDecoration::operator zxdg_toplevel_decoration_v1 *() const
188{
189 return d->xdgdecoration;
190}
191
192bool XdgDecoration::isValid() const
193{
194 return d->xdgdecoration.isValid();
195}
196
197void XdgDecoration::setMode(XdgDecoration::Mode mode)
198{
199 Q_ASSERT(isValid());
200 uint32_t mode_raw;
201 switch (mode) {
202 case XdgDecoration::Mode::ClientSide:
203 mode_raw = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
204 break;
205 default:
206 mode_raw = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
207 break;
208 }
209 zxdg_toplevel_decoration_v1_set_mode(zxdg_toplevel_decoration_v1: d->xdgdecoration, mode: mode_raw);
210}
211
212void XdgDecoration::unsetMode()
213{
214 Q_ASSERT(isValid());
215 zxdg_toplevel_decoration_v1_unset_mode(zxdg_toplevel_decoration_v1: d->xdgdecoration);
216}
217
218XdgDecoration::Mode XdgDecoration::mode() const
219{
220 return d->m_mode;
221}
222
223}
224}
225
226#include "moc_xdgdecoration.cpp"
227

source code of kwayland/src/client/xdgdecoration.cpp