diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9775098b..a4e400d1 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 00000000..b70bec12
--- /dev/null
+++ b/protocols/kde-server-decoration.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+
+
+
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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.
+
+
+
+
+
diff --git a/protocols/meson.build b/protocols/meson.build
index ce89e7f1..1c9013f0 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 9609cbd1..1f5a355c 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 f252d131..8be1956c 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 73611fb2..6df38267 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -60,7 +60,6 @@ extern "C" {
#include
#include
#include
-#include
#include
#include
#include
diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp
index 115e10f4..47372d01 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(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
- PROTO::fractional = std::make_unique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
- PROTO::xdgOutput = std::make_unique(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
- PROTO::cursorShape = std::make_unique(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
- PROTO::idleInhibit = std::make_unique(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit");
- PROTO::relativePointer = std::make_unique(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer");
- PROTO::xdgDecoration = std::make_unique(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration");
- PROTO::alphaModifier = std::make_unique(&wp_alpha_modifier_v1_interface, 1, "AlphaModifier");
- PROTO::gamma = std::make_unique(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl");
- PROTO::foreignToplevel = std::make_unique(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
- PROTO::pointerGestures = std::make_unique(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
- PROTO::foreignToplevelWlr = std::make_unique(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr");
- PROTO::shortcutsInhibit = std::make_unique(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit");
- PROTO::textInputV3 = std::make_unique(&zwp_text_input_manager_v3_interface, 1, "TextInputV3");
- PROTO::constraints = std::make_unique(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints");
- PROTO::outputPower = std::make_unique(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
- PROTO::activation = std::make_unique(&xdg_activation_v1_interface, 1, "XDGActivation");
- PROTO::idle = std::make_unique(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
- PROTO::sessionLock = std::make_unique(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
- PROTO::ime = std::make_unique(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
- PROTO::virtualKeyboard = std::make_unique(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
- PROTO::virtualPointer = std::make_unique(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer");
- PROTO::outputManagement = std::make_unique(&zwlr_output_manager_v1_interface, 4, "OutputManagement");
+ PROTO::tearing = std::make_unique(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
+ PROTO::fractional = std::make_unique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
+ PROTO::xdgOutput = std::make_unique(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
+ PROTO::cursorShape = std::make_unique(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape");
+ PROTO::idleInhibit = std::make_unique(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit");
+ PROTO::relativePointer = std::make_unique(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer");
+ PROTO::xdgDecoration = std::make_unique(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration");
+ PROTO::alphaModifier = std::make_unique(&wp_alpha_modifier_v1_interface, 1, "AlphaModifier");
+ PROTO::gamma = std::make_unique(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl");
+ PROTO::foreignToplevel = std::make_unique(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
+ PROTO::pointerGestures = std::make_unique(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
+ PROTO::foreignToplevelWlr = std::make_unique(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr");
+ PROTO::shortcutsInhibit = std::make_unique(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit");
+ PROTO::textInputV3 = std::make_unique(&zwp_text_input_manager_v3_interface, 1, "TextInputV3");
+ PROTO::constraints = std::make_unique(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints");
+ PROTO::outputPower = std::make_unique(&zwlr_output_power_manager_v1_interface, 1, "OutputPower");
+ PROTO::activation = std::make_unique(&xdg_activation_v1_interface, 1, "XDGActivation");
+ PROTO::idle = std::make_unique(&ext_idle_notifier_v1_interface, 1, "IdleNotify");
+ PROTO::sessionLock = std::make_unique(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
+ PROTO::ime = std::make_unique(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
+ PROTO::virtualKeyboard = std::make_unique(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
+ PROTO::virtualPointer = std::make_unique(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer");
+ PROTO::outputManagement = std::make_unique(&zwlr_output_manager_v1_interface, 4, "OutputManagement");
+ PROTO::serverDecorationKDE = std::make_unique(&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 00000000..8d0e423b
--- /dev/null
+++ b/src/protocols/ServerDecorationKDE.cpp
@@ -0,0 +1,53 @@
+#include "ServerDecorationKDE.hpp"
+
+#define LOGM PROTO::serverDecorationKDE->protoLog
+
+CServerDecorationKDE::CServerDecorationKDE(SP 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(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(std::make_shared(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 00000000..ec7a852f
--- /dev/null
+++ b/src/protocols/ServerDecorationKDE.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include
+#include
+#include
+#include "WaylandProtocol.hpp"
+#include "kde-server-decoration.hpp"
+
+class CServerDecorationKDE {
+ public:
+ CServerDecorationKDE(SP resource_, wlr_surface* surf);
+
+ bool good();
+
+ private:
+ SP 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> m_vManagers;
+ std::vector> m_vDecos;
+
+ friend class CServerDecorationKDE;
+};
+
+namespace PROTO {
+ inline UP serverDecorationKDE;
+};