diff options
| author | Vaxry <vaxry@vaxry.net> | 2025-04-29 18:32:21 +0100 |
|---|---|---|
| committer | Vaxry <vaxry@vaxry.net> | 2025-04-29 18:32:21 +0100 |
| commit | 23ecce0e7a2f21b4048a84d469c0d956aff46ce7 (patch) | |
| tree | 50fcd766cebe367e9e28a6a431db0f0c0d095b1a /src/protocols | |
| parent | 465e3d979d72da90ea4f715393a0d6d3098830b1 (diff) | |
protocols: add support for xdg-system-bell-v1
Diffstat (limited to 'src/protocols')
| -rw-r--r-- | src/protocols/XDGBell.cpp | 64 | ||||
| -rw-r--r-- | src/protocols/XDGBell.hpp | 34 |
2 files changed, 98 insertions, 0 deletions
diff --git a/src/protocols/XDGBell.cpp b/src/protocols/XDGBell.cpp new file mode 100644 index 00000000..42fd6040 --- /dev/null +++ b/src/protocols/XDGBell.cpp @@ -0,0 +1,64 @@ +#include "XDGBell.hpp" +#include "XDGShell.hpp" +#include "../desktop/Window.hpp" +#include "../managers/EventManager.hpp" +#include "../Compositor.hpp" + +CXDGSystemBellManagerResource::CXDGSystemBellManagerResource(UP<CXdgSystemBellV1>&& resource) : m_resource(std::move(resource)) { + if UNLIKELY (!good()) + return; + + m_resource->setDestroy([this](CXdgSystemBellV1* r) { PROTO::xdgBell->destroyResource(this); }); + m_resource->setOnDestroy([this](CXdgSystemBellV1* r) { PROTO::xdgBell->destroyResource(this); }); + + resource->setRing([](CXdgSystemBellV1* r, wl_resource* toplevel) { + auto TOPLEVEL = CXDGToplevelResource::fromResource(toplevel); + + if (!TOPLEVEL) { + g_pEventManager->postEvent(SHyprIPCEvent{ + .event = "bell", + .data = "", + }); + return; + } + + for (const auto& w : g_pCompositor->m_windows) { + if (!w->m_isMapped || w->m_isX11 || !w->m_xdgSurface) + continue; + + if (w->m_xdgSurface == TOPLEVEL->owner) { + g_pEventManager->postEvent(SHyprIPCEvent{ + .event = "bell", + .data = std::format("{:x}", (uintptr_t)w.get()), + }); + return; + } + } + + g_pEventManager->postEvent(SHyprIPCEvent{ + .event = "bell", + .data = "", + }); + }); +} + +bool CXDGSystemBellManagerResource::good() { + return m_resource->resource(); +} + +CXDGSystemBellProtocol::CXDGSystemBellProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CXDGSystemBellProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = WP<CXDGSystemBellManagerResource>{m_vManagers.emplace_back(makeUnique<CXDGSystemBellManagerResource>(makeUnique<CXdgSystemBellV1>(client, ver, id)))}; + + if UNLIKELY (!RESOURCE->good()) { + wl_client_post_no_memory(client); + return; + } +} + +void CXDGSystemBellProtocol::destroyResource(CXDGSystemBellManagerResource* res) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; }); +} diff --git a/src/protocols/XDGBell.hpp b/src/protocols/XDGBell.hpp new file mode 100644 index 00000000..ff385059 --- /dev/null +++ b/src/protocols/XDGBell.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include <vector> +#include "WaylandProtocol.hpp" +#include "xdg-system-bell-v1.hpp" + +class CXDGSystemBellManagerResource { + public: + CXDGSystemBellManagerResource(UP<CXdgSystemBellV1>&& resource); + + bool good(); + + private: + UP<CXdgSystemBellV1> m_resource; +}; + +class CXDGSystemBellProtocol : public IWaylandProtocol { + public: + CXDGSystemBellProtocol(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(CXDGSystemBellManagerResource* res); + + // + std::vector<UP<CXDGSystemBellManagerResource>> m_vManagers; + + friend class CXDGSystemBellManagerResource; +}; + +namespace PROTO { + inline UP<CXDGSystemBellProtocol> xdgBell; +}; |
