File indexing completed on 2024-11-10 04:57:32
0001 /* 0002 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "server_decoration.h" 0007 #include "display.h" 0008 #include "surface.h" 0009 #include "utils/common.h" 0010 0011 #include <QList> 0012 0013 #include <optional> 0014 0015 #include <qwayland-server-server-decoration.h> 0016 0017 namespace KWin 0018 { 0019 static const quint32 s_version = 1; 0020 0021 class ServerSideDecorationManagerInterfacePrivate : public QtWaylandServer::org_kde_kwin_server_decoration_manager 0022 { 0023 public: 0024 ServerSideDecorationManagerInterfacePrivate(ServerSideDecorationManagerInterface *_q, Display *display); 0025 void setDefaultMode(ServerSideDecorationManagerInterface::Mode mode); 0026 0027 ServerSideDecorationManagerInterface::Mode defaultMode = ServerSideDecorationManagerInterface::Mode::None; 0028 ServerSideDecorationManagerInterface *q; 0029 0030 protected: 0031 void org_kde_kwin_server_decoration_manager_bind_resource(Resource *resource) override; 0032 void org_kde_kwin_server_decoration_manager_create(Resource *resource, uint32_t id, wl_resource *surface) override; 0033 }; 0034 0035 static uint32_t modeWayland(ServerSideDecorationManagerInterface::Mode mode) 0036 { 0037 switch (mode) { 0038 case ServerSideDecorationManagerInterface::Mode::None: 0039 return ServerSideDecorationManagerInterfacePrivate::mode_None; 0040 case ServerSideDecorationManagerInterface::Mode::Client: 0041 return ServerSideDecorationManagerInterfacePrivate::mode_Client; 0042 case ServerSideDecorationManagerInterface::Mode::Server: 0043 return ServerSideDecorationManagerInterfacePrivate::mode_Server; 0044 default: 0045 Q_UNREACHABLE(); 0046 } 0047 } 0048 0049 void ServerSideDecorationManagerInterfacePrivate::org_kde_kwin_server_decoration_manager_create(Resource *resource, uint32_t id, wl_resource *surface) 0050 { 0051 SurfaceInterface *s = SurfaceInterface::get(surface); 0052 if (!s) { 0053 wl_resource_post_error(resource->handle, 0, "Invalid surface"); 0054 return; 0055 } 0056 0057 wl_resource *decorationResource = wl_resource_create(resource->client(), &org_kde_kwin_server_decoration_interface, resource->version(), id); 0058 if (!decorationResource) { 0059 wl_client_post_no_memory(resource->client()); 0060 return; 0061 } 0062 auto decoration = new ServerSideDecorationInterface(q, s, decorationResource); 0063 decoration->setMode(defaultMode); 0064 Q_EMIT q->decorationCreated(decoration); 0065 } 0066 0067 void ServerSideDecorationManagerInterfacePrivate::setDefaultMode(ServerSideDecorationManagerInterface::Mode mode) 0068 { 0069 defaultMode = mode; 0070 const uint32_t wlMode = modeWayland(mode); 0071 0072 const auto clientResources = resourceMap(); 0073 for (Resource *resource : clientResources) { 0074 send_default_mode(resource->handle, wlMode); 0075 } 0076 } 0077 0078 ServerSideDecorationManagerInterfacePrivate::ServerSideDecorationManagerInterfacePrivate(ServerSideDecorationManagerInterface *_q, Display *display) 0079 : QtWaylandServer::org_kde_kwin_server_decoration_manager(*display, s_version) 0080 , q(_q) 0081 { 0082 } 0083 0084 void ServerSideDecorationManagerInterfacePrivate::org_kde_kwin_server_decoration_manager_bind_resource(Resource *resource) 0085 { 0086 send_default_mode(resource->handle, modeWayland(defaultMode)); 0087 } 0088 0089 ServerSideDecorationManagerInterface::ServerSideDecorationManagerInterface(Display *display, QObject *parent) 0090 : QObject(parent) 0091 , d(new ServerSideDecorationManagerInterfacePrivate(this, display)) 0092 { 0093 } 0094 0095 ServerSideDecorationManagerInterface::~ServerSideDecorationManagerInterface() = default; 0096 0097 void ServerSideDecorationManagerInterface::setDefaultMode(Mode mode) 0098 { 0099 d->setDefaultMode(mode); 0100 } 0101 0102 ServerSideDecorationManagerInterface::Mode ServerSideDecorationManagerInterface::defaultMode() const 0103 { 0104 return d->defaultMode; 0105 } 0106 0107 class ServerSideDecorationInterfacePrivate : public QtWaylandServer::org_kde_kwin_server_decoration 0108 { 0109 public: 0110 ServerSideDecorationInterfacePrivate(ServerSideDecorationManagerInterface *manager, 0111 ServerSideDecorationInterface *_q, 0112 SurfaceInterface *surface, 0113 wl_resource *resource); 0114 ~ServerSideDecorationInterfacePrivate(); 0115 0116 static ServerSideDecorationInterface *get(SurfaceInterface *surface); 0117 void setMode(ServerSideDecorationManagerInterface::Mode mode); 0118 0119 ServerSideDecorationManagerInterface *manager; 0120 ServerSideDecorationManagerInterface::Mode mode = ServerSideDecorationManagerInterface::Mode::None; 0121 std::optional<ServerSideDecorationManagerInterface::Mode> preferredMode; 0122 SurfaceInterface *surface; 0123 0124 private: 0125 ServerSideDecorationInterface *q; 0126 static QList<ServerSideDecorationInterfacePrivate *> s_all; 0127 0128 protected: 0129 void org_kde_kwin_server_decoration_destroy_resource(Resource *resource) override; 0130 void org_kde_kwin_server_decoration_release(Resource *resource) override; 0131 void org_kde_kwin_server_decoration_request_mode(Resource *resource, uint32_t mode) override; 0132 }; 0133 0134 QList<ServerSideDecorationInterfacePrivate *> ServerSideDecorationInterfacePrivate::s_all; 0135 0136 void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_request_mode(Resource *resource, uint32_t mode) 0137 { 0138 ServerSideDecorationManagerInterface::Mode m = ServerSideDecorationManagerInterface::Mode::None; 0139 switch (mode) { 0140 case ServerSideDecorationManagerInterfacePrivate::mode_None: 0141 m = ServerSideDecorationManagerInterface::Mode::None; 0142 break; 0143 case ServerSideDecorationManagerInterfacePrivate::mode_Client: 0144 m = ServerSideDecorationManagerInterface::Mode::Client; 0145 break; 0146 case ServerSideDecorationManagerInterfacePrivate::mode_Server: 0147 m = ServerSideDecorationManagerInterface::Mode::Server; 0148 break; 0149 default: 0150 // invalid mode 0151 qCWarning(KWIN_CORE) << "Invalid mode:" << mode; 0152 return; 0153 } 0154 preferredMode = m; 0155 Q_EMIT q->preferredModeChanged(); 0156 } 0157 0158 void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_release(Resource *resource) 0159 { 0160 wl_resource_destroy(resource->handle); 0161 } 0162 0163 void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_destroy_resource(Resource *resource) 0164 { 0165 delete q; 0166 } 0167 0168 ServerSideDecorationInterface *ServerSideDecorationInterfacePrivate::get(SurfaceInterface *surface) 0169 { 0170 for (ServerSideDecorationInterfacePrivate *decoration : std::as_const(s_all)) { 0171 if (decoration->surface == surface) { 0172 return decoration->q; 0173 } 0174 } 0175 return nullptr; 0176 } 0177 0178 ServerSideDecorationInterfacePrivate::ServerSideDecorationInterfacePrivate(ServerSideDecorationManagerInterface *manager, 0179 ServerSideDecorationInterface *_q, 0180 SurfaceInterface *surface, 0181 wl_resource *resource) 0182 : QtWaylandServer::org_kde_kwin_server_decoration(resource) 0183 , manager(manager) 0184 , surface(surface) 0185 , q(_q) 0186 { 0187 s_all << this; 0188 } 0189 0190 ServerSideDecorationInterfacePrivate::~ServerSideDecorationInterfacePrivate() 0191 { 0192 s_all.removeAll(this); 0193 } 0194 0195 void ServerSideDecorationInterfacePrivate::setMode(ServerSideDecorationManagerInterface::Mode mode) 0196 { 0197 this->mode = mode; 0198 send_mode(modeWayland(mode)); 0199 } 0200 0201 ServerSideDecorationInterface::ServerSideDecorationInterface(ServerSideDecorationManagerInterface *manager, SurfaceInterface *surface, wl_resource *resource) 0202 : QObject() 0203 , d(new ServerSideDecorationInterfacePrivate(manager, this, surface, resource)) 0204 { 0205 } 0206 0207 ServerSideDecorationInterface::~ServerSideDecorationInterface() = default; 0208 0209 void ServerSideDecorationInterface::setMode(ServerSideDecorationManagerInterface::Mode mode) 0210 { 0211 d->setMode(mode); 0212 } 0213 0214 ServerSideDecorationManagerInterface::Mode ServerSideDecorationInterface::mode() const 0215 { 0216 return d->mode; 0217 } 0218 0219 ServerSideDecorationManagerInterface::Mode ServerSideDecorationInterface::preferredMode() const 0220 { 0221 return d->preferredMode.value_or(d->manager->defaultMode()); 0222 } 0223 0224 SurfaceInterface *ServerSideDecorationInterface::surface() const 0225 { 0226 return d->surface; 0227 } 0228 0229 ServerSideDecorationInterface *ServerSideDecorationInterface::get(SurfaceInterface *surface) 0230 { 0231 return ServerSideDecorationInterfacePrivate::get(surface); 0232 } 0233 0234 } 0235 0236 #include "moc_server_decoration.cpp"