File indexing completed on 2024-12-22 05:09:25

0001 /*
0002     SPDX-FileCopyrightText: 2018 David Edmundson <kde@davidedmundson.co.uk>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "xdgdecoration.h"
0007 
0008 #include "event_queue.h"
0009 #include "wayland_pointer_p.h"
0010 #include "xdgshell.h"
0011 
0012 #include <QDebug>
0013 
0014 #include "wayland-xdg-decoration-unstable-v1-client-protocol.h"
0015 
0016 namespace KWayland
0017 {
0018 namespace Client
0019 {
0020 class Q_DECL_HIDDEN XdgDecorationManager::Private
0021 {
0022 public:
0023     Private() = default;
0024 
0025     void setup(zxdg_decoration_manager_v1 *arg);
0026 
0027     WaylandPointer<zxdg_decoration_manager_v1, zxdg_decoration_manager_v1_destroy> xdgdecorationmanager;
0028     EventQueue *queue = nullptr;
0029 };
0030 
0031 XdgDecorationManager::XdgDecorationManager(QObject *parent)
0032     : QObject(parent)
0033     , d(new Private)
0034 {
0035 }
0036 
0037 void XdgDecorationManager::Private::setup(zxdg_decoration_manager_v1 *arg)
0038 {
0039     Q_ASSERT(arg);
0040     Q_ASSERT(!xdgdecorationmanager);
0041     xdgdecorationmanager.setup(arg);
0042 }
0043 
0044 XdgDecorationManager::~XdgDecorationManager()
0045 {
0046     release();
0047 }
0048 
0049 void XdgDecorationManager::setup(zxdg_decoration_manager_v1 *xdgdecorationmanager)
0050 {
0051     d->setup(xdgdecorationmanager);
0052 }
0053 
0054 void XdgDecorationManager::release()
0055 {
0056     d->xdgdecorationmanager.release();
0057 }
0058 
0059 void XdgDecorationManager::destroy()
0060 {
0061     d->xdgdecorationmanager.destroy();
0062 }
0063 
0064 XdgDecorationManager::operator zxdg_decoration_manager_v1 *()
0065 {
0066     return d->xdgdecorationmanager;
0067 }
0068 
0069 XdgDecorationManager::operator zxdg_decoration_manager_v1 *() const
0070 {
0071     return d->xdgdecorationmanager;
0072 }
0073 
0074 bool XdgDecorationManager::isValid() const
0075 {
0076     return d->xdgdecorationmanager.isValid();
0077 }
0078 
0079 void XdgDecorationManager::setEventQueue(EventQueue *queue)
0080 {
0081     d->queue = queue;
0082 }
0083 
0084 EventQueue *XdgDecorationManager::eventQueue()
0085 {
0086     return d->queue;
0087 }
0088 
0089 XdgDecoration *XdgDecorationManager::getToplevelDecoration(XdgShellSurface *toplevel, QObject *parent)
0090 {
0091     Q_ASSERT(isValid());
0092     xdg_toplevel *toplevel_resource = *toplevel;
0093     if (!toplevel_resource) { // i.e using XDGShellV5
0094         qWarning() << "Trying to create an XdgDecoration without an XDGShell stable toplevel object";
0095         return nullptr;
0096     }
0097     auto p = new XdgDecoration(parent);
0098     auto w = zxdg_decoration_manager_v1_get_toplevel_decoration(d->xdgdecorationmanager, toplevel_resource);
0099     if (d->queue) {
0100         d->queue->addProxy(w);
0101     }
0102     p->setup(w);
0103     return p;
0104 }
0105 
0106 class Q_DECL_HIDDEN XdgDecoration::Private
0107 {
0108 public:
0109     Private(XdgDecoration *q);
0110 
0111     void setup(zxdg_toplevel_decoration_v1 *arg);
0112 
0113     WaylandPointer<zxdg_toplevel_decoration_v1, zxdg_toplevel_decoration_v1_destroy> xdgdecoration;
0114 
0115     XdgDecoration::Mode m_mode = XdgDecoration::Mode::ClientSide;
0116 
0117 private:
0118     XdgDecoration *q;
0119 
0120 private:
0121     static void configureCallback(void *data, zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode);
0122 
0123     static const zxdg_toplevel_decoration_v1_listener s_listener;
0124 };
0125 
0126 const zxdg_toplevel_decoration_v1_listener XdgDecoration::Private::s_listener = {configureCallback};
0127 
0128 void XdgDecoration::Private::configureCallback(void *data, zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t m)
0129 {
0130     auto p = reinterpret_cast<XdgDecoration::Private *>(data);
0131     Q_ASSERT(p->xdgdecoration == zxdg_toplevel_decoration_v1);
0132     switch (m) {
0133     case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
0134         p->m_mode = XdgDecoration::Mode::ClientSide;
0135         break;
0136     case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
0137         p->m_mode = XdgDecoration::Mode::ServerSide;
0138         break;
0139     }
0140     Q_EMIT p->q->modeChanged(p->m_mode);
0141 }
0142 
0143 XdgDecoration::Private::Private(XdgDecoration *q)
0144     : q(q)
0145 {
0146 }
0147 
0148 XdgDecoration::XdgDecoration(QObject *parent)
0149     : QObject(parent)
0150     , d(new Private(this))
0151 {
0152 }
0153 
0154 void XdgDecoration::Private::setup(zxdg_toplevel_decoration_v1 *arg)
0155 {
0156     Q_ASSERT(arg);
0157     Q_ASSERT(!xdgdecoration);
0158     xdgdecoration.setup(arg);
0159     zxdg_toplevel_decoration_v1_add_listener(xdgdecoration, &s_listener, this);
0160 }
0161 
0162 XdgDecoration::~XdgDecoration()
0163 {
0164     release();
0165 }
0166 
0167 void XdgDecoration::setup(zxdg_toplevel_decoration_v1 *xdgdecoration)
0168 {
0169     d->setup(xdgdecoration);
0170 }
0171 
0172 void XdgDecoration::release()
0173 {
0174     d->xdgdecoration.release();
0175 }
0176 
0177 void XdgDecoration::destroy()
0178 {
0179     d->xdgdecoration.destroy();
0180 }
0181 
0182 XdgDecoration::operator zxdg_toplevel_decoration_v1 *()
0183 {
0184     return d->xdgdecoration;
0185 }
0186 
0187 XdgDecoration::operator zxdg_toplevel_decoration_v1 *() const
0188 {
0189     return d->xdgdecoration;
0190 }
0191 
0192 bool XdgDecoration::isValid() const
0193 {
0194     return d->xdgdecoration.isValid();
0195 }
0196 
0197 void XdgDecoration::setMode(XdgDecoration::Mode mode)
0198 {
0199     Q_ASSERT(isValid());
0200     uint32_t mode_raw;
0201     switch (mode) {
0202     case XdgDecoration::Mode::ClientSide:
0203         mode_raw = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
0204         break;
0205     default:
0206         mode_raw = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
0207         break;
0208     }
0209     zxdg_toplevel_decoration_v1_set_mode(d->xdgdecoration, mode_raw);
0210 }
0211 
0212 void XdgDecoration::unsetMode()
0213 {
0214     Q_ASSERT(isValid());
0215     zxdg_toplevel_decoration_v1_unset_mode(d->xdgdecoration);
0216 }
0217 
0218 XdgDecoration::Mode XdgDecoration::mode() const
0219 {
0220     return d->m_mode;
0221 }
0222 
0223 }
0224 }
0225 
0226 #include "moc_xdgdecoration.cpp"