From 62eadad20fe10ffaf13d9c65ee68608996d93df0 Mon Sep 17 00:00:00 2001 From: Vaxry 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 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; +};