summaryrefslogtreecommitdiff
path: root/src/protocols/AlphaModifier.cpp
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-04-21 21:21:22 +0100
committerVaxry <vaxry@vaxry.net>2024-04-21 21:21:22 +0100
commitf587c3e0ba92109302032f89321d94b5d0f89236 (patch)
tree65034aed209a3e10c41a15c6a30d30bf526adf72 /src/protocols/AlphaModifier.cpp
parent87173bd09daa4b56adabcfc72a29aec957cb8a13 (diff)
alpha-modifier: add support for protocol
Diffstat (limited to 'src/protocols/AlphaModifier.cpp')
-rw-r--r--src/protocols/AlphaModifier.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp
new file mode 100644
index 00000000..12bc3512
--- /dev/null
+++ b/src/protocols/AlphaModifier.cpp
@@ -0,0 +1,121 @@
+#include "AlphaModifier.hpp"
+#include <algorithm>
+#include "../desktop/WLSurface.hpp"
+#include "../render/Renderer.hpp"
+
+CAlphaModifier::CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, wlr_surface* surface_) : resource(resource_), pSurface(surface_) {
+ if (!resource->resource())
+ return;
+
+ resource->setDestroy([this](CWpAlphaModifierSurfaceV1* pMgr) {
+ PROTO::alphaModifier->destroyModifier(this);
+ setSurfaceAlpha(1.F);
+ });
+ resource->setOnDestroy([this](CWpAlphaModifierSurfaceV1* pMgr) {
+ PROTO::alphaModifier->destroyModifier(this);
+ setSurfaceAlpha(1.F);
+ });
+
+ hyprListener_surfaceDestroy.initCallback(
+ &surface_->events.destroy, [this](void* owner, void* data) { onSurfaceDestroy(); }, this, "CAlphaModifier");
+
+ resource->setSetMultiplier([this](CWpAlphaModifierSurfaceV1* mod, uint32_t alpha) {
+ if (!pSurface) {
+ wl_resource_post_error(mod->resource(), WP_ALPHA_MODIFIER_SURFACE_V1_ERROR_NO_SURFACE, "Surface is gone");
+ return;
+ }
+
+ float a = alpha / (float)UINT32_MAX;
+
+ setSurfaceAlpha(a);
+ });
+}
+
+CAlphaModifier::~CAlphaModifier() {
+ hyprListener_surfaceDestroy.removeCallback();
+}
+
+bool CAlphaModifier::good() {
+ return resource->resource();
+}
+
+wlr_surface* CAlphaModifier::getSurface() {
+ return pSurface;
+}
+
+void CAlphaModifier::setSurfaceAlpha(float a) {
+ CWLSurface* surf = CWLSurface::surfaceFromWlr(pSurface);
+
+ if (!surf) {
+ Debug::log(ERR, "Error in CAlphaModifier::setSurfaceAlpha: No CWLSurface for given surface??");
+ return;
+ }
+
+ surf->m_pAlphaModifier = a;
+
+ auto SURFBOX = surf->getSurfaceBoxGlobal();
+ if (SURFBOX.has_value())
+ g_pHyprRenderer->damageBox(&*SURFBOX);
+}
+
+void CAlphaModifier::onSurfaceDestroy() {
+ hyprListener_surfaceDestroy.removeCallback();
+ pSurface = nullptr;
+}
+
+CAlphaModifierProtocol::CAlphaModifierProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
+ ;
+}
+
+void CAlphaModifierProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
+ const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CWpAlphaModifierV1>(client, ver, id)).get();
+ RESOURCE->setOnDestroy([this](CWpAlphaModifierV1* p) { this->onManagerResourceDestroy(p->resource()); });
+
+ RESOURCE->setDestroy([this](CWpAlphaModifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
+ RESOURCE->setGetSurface([this](CWpAlphaModifierV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetSurface(pMgr, id, wlr_surface_from_resource(surface)); });
+}
+
+void CAlphaModifierProtocol::onManagerResourceDestroy(wl_resource* res) {
+ std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
+}
+
+void CAlphaModifierProtocol::destroyModifier(CAlphaModifier* modifier) {
+ if (modifier->getSurface())
+ m_mAlphaModifiers.erase(modifier->getSurface());
+ else {
+ // find it first
+ wlr_surface* deadptr = nullptr;
+ for (auto& [k, v] : m_mAlphaModifiers) {
+ if (v.get() == modifier) {
+ deadptr = k;
+ break;
+ }
+ }
+
+ if (!deadptr) {
+ Debug::log(ERR, "CAlphaModifierProtocol::destroyModifier: dead resource but no deadptr???");
+ return;
+ }
+
+ m_mAlphaModifiers.erase(deadptr);
+ }
+}
+
+void CAlphaModifierProtocol::onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, wlr_surface* surface) {
+ if (m_mAlphaModifiers.contains(surface)) {
+ wl_resource_post_error(pMgr->resource(), WP_ALPHA_MODIFIER_V1_ERROR_ALREADY_CONSTRUCTED, "AlphaModifier already present");
+ return;
+ }
+
+ const auto CLIENT = wl_resource_get_client(pMgr->resource());
+ const auto RESOURCE =
+ m_mAlphaModifiers
+ .emplace(surface, std::make_unique<CAlphaModifier>(std::make_shared<CWpAlphaModifierSurfaceV1>(CLIENT, wl_resource_get_version(pMgr->resource()), id), surface))
+ .first->second.get();
+
+ if (!RESOURCE->good()) {
+ wl_resource_post_no_memory(pMgr->resource());
+ m_mAlphaModifiers.erase(surface);
+ return;
+ }
+} \ No newline at end of file