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"