From a4f7d7c594c70408f299ec8b794211c534709eaa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 21 Apr 2025 22:22:06 +0100 Subject: protocols: add xdg_toplevel_tag_v1 support Adds a new windowrule to target windows by xdgTag, xdgtag: --- src/protocols/XDGShell.hpp | 2 ++ src/protocols/XDGTag.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/protocols/XDGTag.hpp | 36 +++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 src/protocols/XDGTag.cpp create mode 100644 src/protocols/XDGTag.hpp (limited to 'src/protocols') diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp index b46e0236..12f76774 100644 --- a/src/protocols/XDGShell.hpp +++ b/src/protocols/XDGShell.hpp @@ -141,6 +141,8 @@ class CXDGToplevelResource { WP parent; WP dialog; + std::optional m_toplevelTag, m_toplevelDescription; + bool anyChildModal(); std::vector> children; diff --git a/src/protocols/XDGTag.cpp b/src/protocols/XDGTag.cpp new file mode 100644 index 00000000..9176882e --- /dev/null +++ b/src/protocols/XDGTag.cpp @@ -0,0 +1,54 @@ +#include "XDGTag.hpp" +#include "XDGShell.hpp" + +CXDGToplevelTagManagerResource::CXDGToplevelTagManagerResource(UP&& resource) : m_resource(std::move(resource)) { + if UNLIKELY (!good()) + return; + + m_resource->setDestroy([this](CXdgToplevelTagManagerV1* r) { PROTO::xdgTag->destroyResource(this); }); + m_resource->setOnDestroy([this](CXdgToplevelTagManagerV1* r) { PROTO::xdgTag->destroyResource(this); }); + + resource->setSetToplevelTag([](CXdgToplevelTagManagerV1* r, wl_resource* toplevel, const char* tag) { + auto TOPLEVEL = CXDGToplevelResource::fromResource(toplevel); + + if (!TOPLEVEL) { + r->error(-1, "Invalid toplevel handle"); + return; + } + + TOPLEVEL->m_toplevelTag = tag; + }); + + resource->setSetToplevelDescription([](CXdgToplevelTagManagerV1* r, wl_resource* toplevel, const char* description) { + auto TOPLEVEL = CXDGToplevelResource::fromResource(toplevel); + + if (!TOPLEVEL) { + r->error(-1, "Invalid toplevel handle"); + return; + } + + TOPLEVEL->m_toplevelDescription = description; + }); +} + +bool CXDGToplevelTagManagerResource::good() { + return m_resource->resource(); +} + +CXDGToplevelTagProtocol::CXDGToplevelTagProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CXDGToplevelTagProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = + WP{m_vManagers.emplace_back(makeUnique(makeUnique(client, ver, id)))}; + + if UNLIKELY (!RESOURCE->good()) { + wl_client_post_no_memory(client); + return; + } +} + +void CXDGToplevelTagProtocol::destroyResource(CXDGToplevelTagManagerResource* res) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; }); +} diff --git a/src/protocols/XDGTag.hpp b/src/protocols/XDGTag.hpp new file mode 100644 index 00000000..cff4da03 --- /dev/null +++ b/src/protocols/XDGTag.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include "WaylandProtocol.hpp" +#include "xdg-toplevel-tag-v1.hpp" + +class CXDGToplevelResource; + +class CXDGToplevelTagManagerResource { + public: + CXDGToplevelTagManagerResource(UP&& resource); + + bool good(); + + private: + UP m_resource; +}; + +class CXDGToplevelTagProtocol : public IWaylandProtocol { + public: + CXDGToplevelTagProtocol(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 destroyResource(CXDGToplevelTagManagerResource* res); + + // + std::vector> m_vManagers; + + friend class CXDGToplevelTagManagerResource; +}; + +namespace PROTO { + inline UP xdgTag; +}; -- cgit v1.2.3