diff --git a/decorations/decorationbridge.cpp b/decorations/decorationbridge.cpp index 68e338a92f..c92e595bf6 100644 --- a/decorations/decorationbridge.cpp +++ b/decorations/decorationbridge.cpp @@ -26,6 +26,7 @@ along with this program. If not, see . #include "client.h" #include "composite.h" #include "scene.h" +#include "wayland_server.h" #include "workspace.h" // KDecoration @@ -33,6 +34,9 @@ along with this program. If not, see . #include #include +// KWayland +#include + // Frameworks #include #include @@ -82,8 +86,12 @@ QString DecorationBridge::readTheme() const void DecorationBridge::init() { + using namespace KWayland::Server; m_noPlugin = readNoPlugin(); if (m_noPlugin) { + if (waylandServer()) { + waylandServer()->decorationManager()->setDefaultMode(ServerSideDecorationManagerInterface::Mode::None); + } return; } m_plugin = readPlugin(); @@ -101,6 +109,9 @@ void DecorationBridge::init() initPlugin(); } } + if (waylandServer()) { + waylandServer()->decorationManager()->setDefaultMode(m_factory ? ServerSideDecorationManagerInterface::Mode::Server : ServerSideDecorationManagerInterface::Mode::None); + } } void DecorationBridge::initPlugin() diff --git a/shell_client.cpp b/shell_client.cpp index 84be59d784..eda91de84c 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -34,6 +34,7 @@ along with this program. If not, see . #include #include #include +#include #include #include @@ -148,6 +149,10 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface) updateCursor(); } ); + // check whether we have a ServerSideDecoration + if (ServerSideDecorationInterface *deco = ServerSideDecorationInterface::get(surface->surface())) { + installServerSideDecoration(deco); + } } ShellClient::~ShellClient() = default; @@ -847,4 +852,29 @@ QMatrix4x4 ShellClient::inputTransformation() const return m; } +void ShellClient::installServerSideDecoration(KWayland::Server::ServerSideDecorationInterface *deco) +{ + if (m_serverDecoration == deco) { + return; + } + m_serverDecoration = deco; + connect(m_serverDecoration, &ServerSideDecorationInterface::destroyed, this, + [this] { + // TODO: update decoration + m_serverDecoration = nullptr; + } + ); + // TODO: update decoration + connect(m_serverDecoration, &ServerSideDecorationInterface::modeRequested, this, + [this] (ServerSideDecorationManagerInterface::Mode mode) { + const bool changed = mode != m_serverDecoration->mode(); + // always acknowledge the requested mode + m_serverDecoration->setMode(mode); + if (changed) { + // TODO: update decoration + } + } + ); +} + } diff --git a/shell_client.h b/shell_client.h index 96f81014e4..67e9da2a41 100644 --- a/shell_client.h +++ b/shell_client.h @@ -27,6 +27,7 @@ namespace KWayland namespace Server { class ShellSurfaceInterface; +class ServerSideDecorationInterface; class PlasmaShellSurfaceInterface; class QtExtendedSurfaceInterface; } @@ -109,6 +110,7 @@ public: void installPlasmaShellSurface(KWayland::Server::PlasmaShellSurfaceInterface *surface); void installQtExtendedSurface(KWayland::Server::QtExtendedSurfaceInterface *surface); + void installServerSideDecoration(KWayland::Server::ServerSideDecorationInterface *decoration); bool isInitialPositionSet() const; @@ -161,6 +163,7 @@ private: NET::WindowType m_windowType = NET::Normal; QPointer m_plasmaShellSurface; QPointer m_qtExtendedSurface; + KWayland::Server::ServerSideDecorationInterface *m_serverDecoration = nullptr; bool m_fullScreen = false; bool m_transient = false; }; diff --git a/wayland_server.cpp b/wayland_server.cpp index 9986c1832b..61e70c42af 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -42,6 +42,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -219,6 +220,16 @@ void WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags) shadowManager->create(); m_display->createDpmsManager(m_display)->create(); + + m_decorationManager = m_display->createServerSideDecorationManager(m_display); + connect(m_decorationManager, &ServerSideDecorationManagerInterface::decorationCreated, this, + [this] (ServerSideDecorationInterface *deco) { + if (ShellClient *c = findClient(deco->surface())) { + c->installServerSideDecoration(deco); + } + } + ); + m_decorationManager->create(); } void WaylandServer::initWorkspace() diff --git a/wayland_server.h b/wayland_server.h index ba40d908c0..5e667563cb 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -43,6 +43,7 @@ class CompositorInterface; class Display; class ShellInterface; class SeatInterface; +class ServerSideDecorationManagerInterface; class SurfaceInterface; class OutputInterface; class PlasmaShellInterface; @@ -89,6 +90,9 @@ public: KWayland::Server::PlasmaWindowManagementInterface *windowManagement() { return m_windowManagement; } + KWayland::Server::ServerSideDecorationManagerInterface *decorationManager() const { + return m_decorationManager; + } QList clients() const { return m_clients; } @@ -164,6 +168,7 @@ private: KWayland::Server::PlasmaShellInterface *m_plasmaShell = nullptr; KWayland::Server::PlasmaWindowManagementInterface *m_windowManagement = nullptr; KWayland::Server::QtSurfaceExtensionInterface *m_qtExtendedSurface = nullptr; + KWayland::Server::ServerSideDecorationManagerInterface *m_decorationManager = nullptr; struct { KWayland::Server::ClientConnection *client = nullptr; QMetaObject::Connection destroyConnection;