From 62eadad20fe10ffaf13d9c65ee68608996d93df0 Mon Sep 17 00:00:00 2001
From: Vaxry <vaxry@vaxry.net>
Date: Sun, 5 May 2024 01:07:46 +0100
Subject: [PATCH] kde-server-decoration: move to new impl

---
 CMakeLists.txt                        |  1 +
 protocols/kde-server-decoration.xml   | 85 +++++++++++++++++++++++++++
 protocols/meson.build                 |  1 +
 src/Compositor.cpp                    |  3 -
 src/Compositor.hpp                    | 45 +++++++-------
 src/includes.hpp                      |  1 -
 src/managers/ProtocolManager.cpp      | 48 +++++++--------
 src/protocols/ServerDecorationKDE.cpp | 53 +++++++++++++++++
 src/protocols/ServerDecorationKDE.hpp | 40 +++++++++++++
 9 files changed, 227 insertions(+), 50 deletions(-)
 create mode 100644 protocols/kde-server-decoration.xml
 create mode 100644 src/protocols/ServerDecorationKDE.cpp
 create mode 100644 src/protocols/ServerDecorationKDE.hpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9775098ba..a4e400d1e 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -265,6 +265,7 @@ protocolNew("protocols/virtual-keyboard-unstable-v1.xml" "virtual-keyboard-unsta
 protocolNew("protocols/wlr-virtual-pointer-unstable-v1.xml" "wlr-virtual-pointer-unstable-v1" true)
 protocolNew("protocols/input-method-unstable-v2.xml" "input-method-unstable-v2" true)
 protocolNew("protocols/wlr-output-management-unstable-v1.xml" "wlr-output-management-unstable-v1" true)
+protocolNew("protocols/kde-server-decoration.xml" "kde-server-decoration" true)
 protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
 protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
 protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
diff --git a/protocols/kde-server-decoration.xml b/protocols/kde-server-decoration.xml
new file mode 100644
index 000000000..b70bec122
--- /dev/null
+++ b/protocols/kde-server-decoration.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="server_decoration">
+  <copyright><![CDATA[
+    SPDX-FileCopyrightText: 2015 Martin Gräßlin
+
+    SPDX-License-Identifier: LGPL-2.1-or-later
+  ]]></copyright>
+  <interface  name="org_kde_kwin_server_decoration_manager" version="1">
+      <description summary="Server side window decoration manager">
+        This interface allows to coordinate whether the server should create
+        a server-side window decoration around a wl_surface representing a
+        shell surface (wl_shell_surface or similar). By announcing support
+        for this interface the server indicates that it supports server
+        side decorations.
+
+        Use in conjunction with zxdg_decoration_manager_v1 is undefined.
+      </description>
+      <request name="create">
+        <description summary="Create a server-side decoration object for a given surface">
+            When a client creates a server-side decoration object it indicates
+            that it supports the protocol. The client is supposed to tell the
+            server whether it wants server-side decorations or will provide
+            client-side decorations.
+
+            If the client does not create a server-side decoration object for
+            a surface the server interprets this as lack of support for this
+            protocol and considers it as client-side decorated. Nevertheless a
+            client-side decorated surface should use this protocol to indicate
+            to the server that it does not want a server-side deco.
+        </description>
+        <arg name="id" type="new_id" interface="org_kde_kwin_server_decoration"/>
+        <arg name="surface" type="object" interface="wl_surface"/>
+      </request>
+      <enum name="mode">
+            <description summary="Possible values to use in request_mode and the event mode."/>
+            <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/>
+            <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/>
+            <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/>
+      </enum>
+      <event name="default_mode">
+          <description summary="The default mode used on the server">
+              This event is emitted directly after binding the interface. It contains
+              the default mode for the decoration. When a new server decoration object
+              is created this new object will be in the default mode until the first
+              request_mode is requested.
+
+              The server may change the default mode at any time.
+          </description>
+          <arg name="mode" type="uint" summary="The default decoration mode applied to newly created server decorations."/>
+      </event>
+  </interface>
+  <interface name="org_kde_kwin_server_decoration" version="1">
+      <request name="release" type="destructor">
+        <description summary="release the server decoration object"/>
+      </request>
+      <enum name="mode">
+            <description summary="Possible values to use in request_mode and the event mode."/>
+            <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/>
+            <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/>
+            <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/>
+      </enum>
+      <request name="request_mode">
+          <description summary="The decoration mode the surface wants to use."/>
+          <arg name="mode" type="uint" summary="The mode this surface wants to use."/>
+      </request>
+      <event name="mode">
+          <description summary="The new decoration mode applied by the server">
+              This event is emitted directly after the decoration is created and
+              represents the base decoration policy by the server. E.g. a server
+              which wants all surfaces to be client-side decorated will send Client,
+              a server which wants server-side decoration will send Server.
+
+              The client can request a different mode through the decoration request.
+              The server will acknowledge this by another event with the same mode. So
+              even if a server prefers server-side decoration it's possible to force a
+              client-side decoration.
+
+              The server may emit this event at any time. In this case the client can
+              again request a different mode. It's the responsibility of the server to
+              prevent a feedback loop.
+          </description>
+          <arg name="mode" type="uint" summary="The decoration mode applied to the surface by the server."/>
+      </event>
+  </interface>
+</protocol>
diff --git a/protocols/meson.build b/protocols/meson.build
index ce89e7f12..1c9013f03 100644
--- a/protocols/meson.build
+++ b/protocols/meson.build
@@ -42,6 +42,7 @@ new_protocols = [
   ['virtual-keyboard-unstable-v1.xml'],
   ['wlr-virtual-pointer-unstable-v1.xml'],
   ['wlr-output-management-unstable-v1.xml'],
+  ['kde-server-decoration.xml'],
   [wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
   [wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
   [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 9609cbd1a..1f5a355cb 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -240,9 +240,6 @@ void CCompositor::initServer() {
 
     m_sWLRLayerShell = wlr_layer_shell_v1_create(m_sWLDisplay, 4);
 
-    m_sWLRServerDecoMgr = wlr_server_decoration_manager_create(m_sWLDisplay);
-    wlr_server_decoration_manager_set_default_mode(m_sWLRServerDecoMgr, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
-
     m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
     if (!m_sWRLDRMLeaseMgr) {
         Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index f252d131d..8be1956c5 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -40,29 +40,28 @@ class CCompositor {
     ~CCompositor();
 
     // ------------------ WLR BASICS ------------------ //
-    wl_display*                    m_sWLDisplay;
-    wl_event_loop*                 m_sWLEventLoop;
-    wlr_backend*                   m_sWLRBackend;
-    wlr_session*                   m_sWLRSession;
-    wlr_renderer*                  m_sWLRRenderer;
-    wlr_allocator*                 m_sWLRAllocator;
-    wlr_compositor*                m_sWLRCompositor;
-    wlr_subcompositor*             m_sWLRSubCompositor;
-    wlr_data_device_manager*       m_sWLRDataDevMgr;
-    wlr_drm*                       m_sWRLDRM;
-    wlr_drm_lease_v1_manager*      m_sWRLDRMLeaseMgr;
-    wlr_output_layout*             m_sWLROutputLayout;
-    wlr_layer_shell_v1*            m_sWLRLayerShell;
-    wlr_xdg_shell*                 m_sWLRXDGShell;
-    wlr_cursor*                    m_sWLRCursor;
-    wlr_presentation*              m_sWLRPresentation;
-    wlr_egl*                       m_sWLREGL;
-    int                            m_iDRMFD;
-    wlr_server_decoration_manager* m_sWLRServerDecoMgr;
-    wlr_tablet_manager_v2*         m_sWLRTabletManager;
-    wlr_xdg_foreign_registry*      m_sWLRForeignRegistry;
-    wlr_linux_dmabuf_v1*           m_sWLRLinuxDMABuf;
-    wlr_backend*                   m_sWLRHeadlessBackend;
+    wl_display*               m_sWLDisplay;
+    wl_event_loop*            m_sWLEventLoop;
+    wlr_backend*              m_sWLRBackend;
+    wlr_session*              m_sWLRSession;
+    wlr_renderer*             m_sWLRRenderer;
+    wlr_allocator*            m_sWLRAllocator;
+    wlr_compositor*           m_sWLRCompositor;
+    wlr_subcompositor*        m_sWLRSubCompositor;
+    wlr_data_device_manager*  m_sWLRDataDevMgr;
+    wlr_drm*                  m_sWRLDRM;
+    wlr_drm_lease_v1_manager* m_sWRLDRMLeaseMgr;
+    wlr_output_layout*        m_sWLROutputLayout;
+    wlr_layer_shell_v1*       m_sWLRLayerShell;
+    wlr_xdg_shell*            m_sWLRXDGShell;
+    wlr_cursor*               m_sWLRCursor;
+    wlr_presentation*         m_sWLRPresentation;
+    wlr_egl*                  m_sWLREGL;
+    int                       m_iDRMFD;
+    wlr_tablet_manager_v2*    m_sWLRTabletManager;
+    wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
+    wlr_linux_dmabuf_v1*      m_sWLRLinuxDMABuf;
+    wlr_backend*              m_sWLRHeadlessBackend;
     // ------------------------------------------------- //
 
     std::string                               m_szHyprTempDataRoot = "";
diff --git a/src/includes.hpp b/src/includes.hpp
index 73611fb29..6df382672 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -60,7 +60,6 @@ extern "C" {
 #include <wlr/types/wlr_primary_selection_v1.h>
 #include <wlr/types/wlr_screencopy_v1.h>
 #include <wlr/types/wlr_seat.h>
-#include <wlr/types/wlr_server_decoration.h>
 #include <wlr/types/wlr_viewporter.h>
 #include <wlr/types/wlr_xdg_output_v1.h>
 #include <wlr/types/wlr_xdg_shell.h>
diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp
index 115e10f44..47372d016 100644
--- a/src/managers/ProtocolManager.cpp
+++ b/src/managers/ProtocolManager.cpp
@@ -23,32 +23,34 @@
 #include "../protocols/VirtualKeyboard.hpp"
 #include "../protocols/VirtualPointer.hpp"
 #include "../protocols/OutputManagement.hpp"
+#include "../protocols/ServerDecorationKDE.hpp"
 
 CProtocolManager::CProtocolManager() {
 
-    PROTO::tearing            = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
-    PROTO::fractional         = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
-    PROTO::xdgOutput          = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
-    PROTO::cursorShape        = std::make_unique<CCursorShapeProtocol>(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
-    PROTO::idleInhibit        = std::make_unique<CIdleInhibitProtocol>(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit");
-    PROTO::relativePointer    = std::make_unique<CRelativePointerProtocol>(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer");
-    PROTO::xdgDecoration      = std::make_unique<CXDGDecorationProtocol>(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration");
-    PROTO::alphaModifier      = std::make_unique<CAlphaModifierProtocol>(&wp_alpha_modifier_v1_interface, 1, "AlphaModifier");
-    PROTO::gamma              = std::make_unique<CGammaControlProtocol>(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl");
-    PROTO::foreignToplevel    = std::make_unique<CForeignToplevelProtocol>(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
-    PROTO::pointerGestures    = std::make_unique<CPointerGesturesProtocol>(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
-    PROTO::foreignToplevelWlr = std::make_unique<CForeignToplevelWlrProtocol>(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr");
-    PROTO::shortcutsInhibit   = std::make_unique<CKeyboardShortcutsInhibitProtocol>(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit");
-    PROTO::textInputV3        = std::make_unique<CTextInputV3Protocol>(&zwp_text_input_manager_v3_interface, 1, "TextInputV3");
-    PROTO::constraints        = std::make_unique<CPointerConstraintsProtocol>(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints");
-    PROTO::outputPower        = std::make_unique<COutputPowerProtocol>(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
-    PROTO::activation         = std::make_unique<CXDGActivationProtocol>(&xdg_activation_v1_interface, 1, "XDGActivation");
-    PROTO::idle               = std::make_unique<CIdleNotifyProtocol>(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
-    PROTO::sessionLock        = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
-    PROTO::ime                = std::make_unique<CInputMethodV2Protocol>(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
-    PROTO::virtualKeyboard    = std::make_unique<CVirtualKeyboardProtocol>(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
-    PROTO::virtualPointer     = std::make_unique<CVirtualPointerProtocol>(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer");
-    PROTO::outputManagement   = std::make_unique<COutputManagementProtocol>(&zwlr_output_manager_v1_interface, 4, "OutputManagement");
+    PROTO::tearing             = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
+    PROTO::fractional          = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
+    PROTO::xdgOutput           = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
+    PROTO::cursorShape         = std::make_unique<CCursorShapeProtocol>(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
+    PROTO::idleInhibit         = std::make_unique<CIdleInhibitProtocol>(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit");
+    PROTO::relativePointer     = std::make_unique<CRelativePointerProtocol>(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer");
+    PROTO::xdgDecoration       = std::make_unique<CXDGDecorationProtocol>(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration");
+    PROTO::alphaModifier       = std::make_unique<CAlphaModifierProtocol>(&wp_alpha_modifier_v1_interface, 1, "AlphaModifier");
+    PROTO::gamma               = std::make_unique<CGammaControlProtocol>(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl");
+    PROTO::foreignToplevel     = std::make_unique<CForeignToplevelProtocol>(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
+    PROTO::pointerGestures     = std::make_unique<CPointerGesturesProtocol>(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
+    PROTO::foreignToplevelWlr  = std::make_unique<CForeignToplevelWlrProtocol>(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr");
+    PROTO::shortcutsInhibit    = std::make_unique<CKeyboardShortcutsInhibitProtocol>(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit");
+    PROTO::textInputV3         = std::make_unique<CTextInputV3Protocol>(&zwp_text_input_manager_v3_interface, 1, "TextInputV3");
+    PROTO::constraints         = std::make_unique<CPointerConstraintsProtocol>(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints");
+    PROTO::outputPower         = std::make_unique<COutputPowerProtocol>(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
+    PROTO::activation          = std::make_unique<CXDGActivationProtocol>(&xdg_activation_v1_interface, 1, "XDGActivation");
+    PROTO::idle                = std::make_unique<CIdleNotifyProtocol>(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
+    PROTO::sessionLock         = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
+    PROTO::ime                 = std::make_unique<CInputMethodV2Protocol>(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
+    PROTO::virtualKeyboard     = std::make_unique<CVirtualKeyboardProtocol>(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
+    PROTO::virtualPointer      = std::make_unique<CVirtualPointerProtocol>(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer");
+    PROTO::outputManagement    = std::make_unique<COutputManagementProtocol>(&zwlr_output_manager_v1_interface, 4, "OutputManagement");
+    PROTO::serverDecorationKDE = std::make_unique<CServerDecorationKDEProtocol>(&org_kde_kwin_server_decoration_manager_interface, 1, "ServerDecorationKDE");
 
     // Old protocol implementations.
     // TODO: rewrite them to use hyprwayland-scanner.
diff --git a/src/protocols/ServerDecorationKDE.cpp b/src/protocols/ServerDecorationKDE.cpp
new file mode 100644
index 000000000..8d0e423b6
--- /dev/null
+++ b/src/protocols/ServerDecorationKDE.cpp
@@ -0,0 +1,53 @@
+#include "ServerDecorationKDE.hpp"
+
+#define LOGM PROTO::serverDecorationKDE->protoLog
+
+CServerDecorationKDE::CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, wlr_surface* surf) : resource(resource_) {
+    if (!good())
+        return;
+
+    resource->setRelease([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); });
+    resource->setOnDestroy([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); });
+
+    // we send this and ignore request_mode.
+    resource->sendMode(ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
+}
+
+bool CServerDecorationKDE::good() {
+    return resource->resource();
+}
+
+CServerDecorationKDEProtocol::CServerDecorationKDEProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
+    ;
+}
+
+void CServerDecorationKDEProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
+    const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<COrgKdeKwinServerDecorationManager>(client, ver, id)).get();
+    RESOURCE->setOnDestroy([this](COrgKdeKwinServerDecorationManager* p) { this->onManagerResourceDestroy(p->resource()); });
+
+    RESOURCE->setCreate([this](COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* pointer) { this->createDecoration(pMgr, id, pointer); });
+
+    // send default mode of SSD, as Hyprland will never ask for CSD. Screw Gnome and GTK.
+    RESOURCE->sendDefaultMode(ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
+}
+
+void CServerDecorationKDEProtocol::onManagerResourceDestroy(wl_resource* res) {
+    std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
+}
+
+void CServerDecorationKDEProtocol::destroyResource(CServerDecorationKDE* hayperlaaaand) {
+    std::erase_if(m_vDecos, [&](const auto& other) { return other.get() == hayperlaaaand; });
+}
+
+void CServerDecorationKDEProtocol::createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf) {
+    const auto CLIENT = pMgr->client();
+    const auto RESOURCE =
+        m_vDecos.emplace_back(std::make_unique<CServerDecorationKDE>(std::make_shared<COrgKdeKwinServerDecoration>(CLIENT, pMgr->version(), id), wlr_surface_from_resource(surf)))
+            .get();
+
+    if (!RESOURCE->good()) {
+        pMgr->noMemory();
+        m_vDecos.pop_back();
+        return;
+    }
+}
diff --git a/src/protocols/ServerDecorationKDE.hpp b/src/protocols/ServerDecorationKDE.hpp
new file mode 100644
index 000000000..ec7a852f7
--- /dev/null
+++ b/src/protocols/ServerDecorationKDE.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+#include <cstdint>
+#include "WaylandProtocol.hpp"
+#include "kde-server-decoration.hpp"
+
+class CServerDecorationKDE {
+  public:
+    CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, wlr_surface* surf);
+
+    bool good();
+
+  private:
+    SP<COrgKdeKwinServerDecoration> resource;
+};
+
+class CServerDecorationKDEProtocol : public IWaylandProtocol {
+  public:
+    CServerDecorationKDEProtocol(const wl_interface* iface, const int& ver, const std::string& name);
+
+    virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
+
+  private:
+    void onManagerResourceDestroy(wl_resource* res);
+    void destroyResource(CServerDecorationKDE* deco);
+
+    void createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf);
+
+    //
+    std::vector<UP<COrgKdeKwinServerDecorationManager>> m_vManagers;
+    std::vector<UP<CServerDecorationKDE>>               m_vDecos;
+
+    friend class CServerDecorationKDE;
+};
+
+namespace PROTO {
+    inline UP<CServerDecorationKDEProtocol> serverDecorationKDE;
+};