From ed69502ff6e79a6dad213333b0bc3a15e2247942 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 21 Apr 2024 20:04:58 +0100 Subject: [PATCH] xdg-decoration: move to new impl --- CMakeLists.txt | 1 + protocols/meson.build | 1 + src/Compositor.cpp | 3 -- src/Compositor.hpp | 1 - src/events/Events.hpp | 3 -- src/events/Windows.cpp | 5 --- src/includes.hpp | 1 - src/managers/ProtocolManager.cpp | 3 ++ src/protocols/XDGDecoration.cpp | 75 ++++++++++++++++++++++++++++++++ src/protocols/XDGDecoration.hpp | 41 +++++++++++++++++ 10 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 src/protocols/XDGDecoration.cpp create mode 100644 src/protocols/XDGDecoration.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 009093ed..d0af966c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -267,6 +267,7 @@ protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstabl protocolNew("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false) protocolNew("unstable/idle-inhibit/idle-inhibit-unstable-v1.xml" "idle-inhibit-unstable-v1" false) protocolNew("unstable/relative-pointer/relative-pointer-unstable-v1.xml" "relative-pointer-unstable-v1" false) +protocolNew("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" "xdg-decoration-unstable-v1" false) # tools add_subdirectory(hyprctl) diff --git a/protocols/meson.build b/protocols/meson.build index 145863a0..842fe9e9 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -45,6 +45,7 @@ new_protocols = [ [wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'], [wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'], [wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], + [wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'], ] wl_protos_src = [] diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 40cf672a..2997bf6e 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -208,7 +208,6 @@ void CCompositor::initServer() { m_sWLRLayerShell = wlr_layer_shell_v1_create(m_sWLDisplay, 4); m_sWLRServerDecoMgr = wlr_server_decoration_manager_create(m_sWLDisplay); - m_sWLRXDGDecoMgr = wlr_xdg_decoration_manager_v1_create(m_sWLDisplay); wlr_server_decoration_manager_set_default_mode(m_sWLRServerDecoMgr, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay); @@ -292,7 +291,6 @@ void CCompositor::initAllSignals() { addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr"); addWLSignal(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest, m_sWLROutputMgr, "OutputMgr"); addWLSignal(&m_sWLRPointerConstraints->events.new_constraint, &Events::listen_newConstraint, m_sWLRPointerConstraints, "PointerConstraints"); - addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr"); addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr"); addWLSignal(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listen_newVirtualKeyboard, m_sWLRVKeyboardMgr, "VKeyboardMgr"); addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer"); @@ -343,7 +341,6 @@ void CCompositor::removeAllSignals() { removeWLSignal(&Events::listen_outputMgrApply); removeWLSignal(&Events::listen_outputMgrTest); removeWLSignal(&Events::listen_newConstraint); - removeWLSignal(&Events::listen_NewXDGDeco); removeWLSignal(&Events::listen_newVirtPtr); removeWLSignal(&Events::listen_newVirtualKeyboard); removeWLSignal(&Events::listen_RendererDestroy); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 812d38fb..af777d03 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -65,7 +65,6 @@ class CCompositor { int m_iDRMFD; wlr_pointer_constraints_v1* m_sWLRPointerConstraints; wlr_server_decoration_manager* m_sWLRServerDecoMgr; - wlr_xdg_decoration_manager_v1* m_sWLRXDGDecoMgr; wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr; wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr; wlr_tablet_manager_v2* m_sWLRTabletManager; diff --git a/src/events/Events.hpp b/src/events/Events.hpp index 4336bfd5..74b81b00 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -99,9 +99,6 @@ namespace Events { DYNLISTENFUNC(destroyDragIcon); DYNLISTENFUNC(commitDragIcon); - // Deco XDG - LISTENER(NewXDGDeco); - // Renderer destroy LISTENER(RendererDestroy); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index b1db5286..a351ef67 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -1232,11 +1232,6 @@ void Events::listener_newXDGToplevel(wl_listener* listener, void* data) { PNEWWINDOW->m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(PNEWWINDOW), PNEWWINDOW); } -void Events::listener_NewXDGDeco(wl_listener* listener, void* data) { - const auto WLRDECO = (wlr_xdg_toplevel_decoration_v1*)data; - wlr_xdg_toplevel_decoration_v1_set_mode(WLRDECO, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); -} - void Events::listener_requestMaximize(void* owner, void* data) { const auto PWINDOW = (CWindow*)owner; diff --git a/src/includes.hpp b/src/includes.hpp index d62994db..3abea9ba 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -64,7 +64,6 @@ extern "C" { #include #include #include -#include #include #include #include diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 77f5315c..47ebbbe0 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -6,6 +6,7 @@ #include "../protocols/CursorShape.hpp" #include "../protocols/IdleInhibit.hpp" #include "../protocols/RelativePointer.hpp" +#include "../protocols/XDGDecoration.hpp" #include "tearing-control-v1.hpp" #include "fractional-scale-v1.hpp" @@ -13,6 +14,7 @@ #include "cursor-shape-v1.hpp" #include "idle-inhibit-unstable-v1.hpp" #include "relative-pointer-unstable-v1.hpp" +#include "xdg-decoration-unstable-v1.hpp" CProtocolManager::CProtocolManager() { @@ -22,6 +24,7 @@ CProtocolManager::CProtocolManager() { 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"); // Old protocol implementations. // TODO: rewrite them to use hyprwayland-scanner. diff --git a/src/protocols/XDGDecoration.cpp b/src/protocols/XDGDecoration.cpp new file mode 100644 index 00000000..0f88870b --- /dev/null +++ b/src/protocols/XDGDecoration.cpp @@ -0,0 +1,75 @@ +#include "XDGDecoration.hpp" +#include + +CXDGDecoration::CXDGDecoration(SP resource_, wl_resource* toplevel) : resource(resource_), pToplevelResource(toplevel) { + if (!resource->resource()) + return; + + resource->setDestroy([this](CZxdgToplevelDecorationV1* pMgr) { PROTO::xdgDecoration->destroyDecoration(this); }); + resource->setOnDestroy([this](CZxdgToplevelDecorationV1* pMgr) { PROTO::xdgDecoration->destroyDecoration(this); }); + + resource->setSetMode([this](CZxdgToplevelDecorationV1*, zxdgToplevelDecorationV1Mode mode) { + std::string modeString; + switch (mode) { + case zxdgToplevelDecorationV1Mode::MODE_CLIENT_SIDE: modeString = "MODE_CLIENT_SIDE"; break; + case zxdgToplevelDecorationV1Mode::MODE_SERVER_SIDE: modeString = "MODE_SERVER_SIDE"; break; + default: modeString = "INVALID"; break; + } + + Debug::log(LOG, "[xdgDecoration] setMode: {}. {} MODE_SERVER_SIDE as reply.", modeString, + (mode == zxdgToplevelDecorationV1Mode::MODE_SERVER_SIDE ? "Sending" : "Ignoring and sending")); + resource->sendConfigure(zxdgToplevelDecorationV1Mode::MODE_SERVER_SIDE); + }); + + resource->setUnsetMode([this](CZxdgToplevelDecorationV1*) { + Debug::log(LOG, "[xdgDecoration] unsetMode. Sending MODE_SERVER_SIDE."); + resource->sendConfigure(zxdgToplevelDecorationV1Mode::MODE_SERVER_SIDE); + }); +} + +bool CXDGDecoration::good() { + return resource->resource(); +} + +wl_resource* CXDGDecoration::toplevelResource() { + return pToplevelResource; +} + +CXDGDecorationProtocol::CXDGDecorationProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CXDGDecorationProtocol::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](CZxdgDecorationManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); + + RESOURCE->setDestroy([this](CZxdgDecorationManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); + RESOURCE->setGetToplevelDecoration([this](CZxdgDecorationManagerV1* pMgr, uint32_t id, wl_resource* xdgToplevel) { this->onGetDecoration(pMgr, id, xdgToplevel); }); +} + +void CXDGDecorationProtocol::onManagerResourceDestroy(wl_resource* res) { + std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; }); +} + +void CXDGDecorationProtocol::destroyDecoration(CXDGDecoration* decoration) { + m_mDecorations.erase(decoration->toplevelResource()); +} + +void CXDGDecorationProtocol::onGetDecoration(CZxdgDecorationManagerV1* pMgr, uint32_t id, wl_resource* xdgToplevel) { + if (m_mDecorations.contains(xdgToplevel)) { + wl_resource_post_error(pMgr->resource(), zxdgToplevelDecorationV1Error::ERROR_ALREADY_CONSTRUCTED, "Decoration object already exists"); + return; + } + + const auto CLIENT = wl_resource_get_client(pMgr->resource()); + const auto RESOURCE = + m_mDecorations + .emplace(xdgToplevel, std::make_unique(std::make_shared(CLIENT, wl_resource_get_version(pMgr->resource()), id), xdgToplevel)) + .first->second.get(); + + if (!RESOURCE->good()) { + wl_resource_post_no_memory(pMgr->resource()); + m_mDecorations.erase(xdgToplevel); + return; + } +} \ No newline at end of file diff --git a/src/protocols/XDGDecoration.hpp b/src/protocols/XDGDecoration.hpp new file mode 100644 index 00000000..cbd74be4 --- /dev/null +++ b/src/protocols/XDGDecoration.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "xdg-decoration-unstable-v1.hpp" + +class CXDGDecoration { + public: + CXDGDecoration(SP resource_, wl_resource* toplevel); + + bool good(); + wl_resource* toplevelResource(); + + private: + SP resource; + wl_resource* pToplevelResource = nullptr; // READ-ONLY. +}; + +class CXDGDecorationProtocol : public IWaylandProtocol { + public: + CXDGDecorationProtocol(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 destroyDecoration(CXDGDecoration* decoration); + void onGetDecoration(CZxdgDecorationManagerV1* pMgr, uint32_t id, wl_resource* xdgToplevel); + + // + std::vector> m_vManagers; + std::unordered_map> m_mDecorations; // xdg_toplevel -> deco + + friend class CXDGDecoration; +}; + +namespace PROTO { + inline UP xdgDecoration; +};