From 41212dc981792af5c42734d7dad2e2e0a5bcac72 Mon Sep 17 00:00:00 2001 From: carlos Date: Wed, 28 Oct 2026 16:06:35 -0400 Subject: [PATCH] [release] port imgborders to the Hyprland 0.57 renderer for Fedora Fedora moved hyprland-devel to 0.57: the renderer passes an explicit CRenderContext, m_renderData is gone, and IPassElement's virtuals changed, so the vendored plugin no longer compiled and the whole Fedora publish stopped. Refresh the vendored bundle to upstream's current commit (plus a Ryoku master that keeps the 0.56 source pins the Arch lane resolves) and carry the 0.57 port as a Fedora fetch-hook patch, so the Arch build keeps choosing the unchanged 0.56.2 source. Verified: git bundle verify; git apply --check on the pinned commit; libimgborders.so links in fedora:44 and fedora:45 containers with hyprland-devel 0.57.0; the Arch resolver still maps 0.56.2 to the same source commit. Note: Fixed: the Fedora repository publish failed because the image-border plugin did not compile against Hyprland 0.57; Fedora now ships a ported build. --- .../rpm/fetch/imgborders-hyprland-0.57.patch | 470 ++++++++++++++++++ fedora/packages/rpm/fetch/imgborders.sh | 9 +- release/CHANGELOG.md | 9 + release/packages/imgborders/PKGBUILD | 2 +- release/packages/imgborders/imgborders.bundle | Bin 58836 -> 64970 bytes 5 files changed, 483 insertions(+), 7 deletions(-) create mode 100644 fedora/packages/rpm/fetch/imgborders-hyprland-0.57.patch diff --git a/fedora/packages/rpm/fetch/imgborders-hyprland-0.57.patch b/fedora/packages/rpm/fetch/imgborders-hyprland-0.57.patch new file mode 100644 index 0000000000..6453e86562 --- /dev/null +++ b/fedora/packages/rpm/fetch/imgborders-hyprland-0.57.patch @@ -0,0 +1,470 @@ +diff --git a/ImgBorder.cpp b/ImgBorder.cpp +index c4a1759..100c361 100644 +--- a/ImgBorder.cpp ++++ b/ImgBorder.cpp +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -48,14 +49,18 @@ void CImgBorder::onPositioningReply(const SDecorationPositioningReply &reply) { + m_assignedBox = reply.assignedGeometry; + } + +-void CImgBorder::draw(PHLMONITOR pMonitor, const float &a) { ++void CImgBorder::draw( ++ Render::CRenderContext &ctx, PHLMONITOR pMonitor, const float &a, ++ const Render::SWindowRenderPresentation &presentation) { + if (!m_isEnabled || m_isHidden || // + !validMapped(m_pWindow) || // + !m_pWindow->m_ruleApplicator->decorate().valueOrDefault()) + return; + +- CImgBorderPassElement::SData data = {.deco = this, .a = a}; +- g_pHyprRenderer->m_renderPass.add(makeUnique(data)); ++ CImgBorderPassElement::SData data = { ++ .deco = this, .a = a, .presentation = presentation}; ++ Render::IHyprRenderer::addPassElement( ++ ctx, makeUnique(data)); + } + + eDecorationType CImgBorder::getDecorationType() { return DECORATION_CUSTOM; } +@@ -63,7 +68,9 @@ eDecorationType CImgBorder::getDecorationType() { return DECORATION_CUSTOM; } + void CImgBorder::updateWindow(PHLWINDOW pWindow) { damageEntire(); } + + void CImgBorder::damageEntire() { +- g_pHyprRenderer->damageBox(getGlobalBoundingBox()); ++ const auto window = m_pWindow.lock(); ++ g_pHyprRenderer->damageBox( ++ getGlobalBoundingBox(window->presentation().renderPresentation())); + } + + eDecorationLayer CImgBorder::getDecorationLayer() { +@@ -80,24 +87,22 @@ PHLWINDOWREF CImgBorder::getWindow() { return m_pWindow; } + + bool CImgBorder::shouldBlur() { return m_shouldBlur; } + +-CBox CImgBorder::getGlobalBoundingBox() { ++CBox CImgBorder::getGlobalBoundingBox( ++ const Render::SWindowRenderPresentation &presentation) { + const auto PWINDOW = m_pWindow.lock(); + + CBox box = m_assignedBox; + box.translate(g_pDecorationPositioner->getEdgeDefinedPoint( + DECORATION_EDGE_TOP | DECORATION_EDGE_LEFT, PWINDOW)); + +- const auto PWORKSPACE = PWINDOW->m_workspace; +- const auto WORKSPACEOFFSET = PWORKSPACE && !PWINDOW->m_pinned +- ? PWORKSPACE->m_renderOffset->value() +- : Vector2D(); +- +- return box.translate(WORKSPACEOFFSET); ++ return box.translate(presentation.workspaceOffset); + } + +-void CImgBorder::drawPass(PHLMONITOR pMonitor, const float &a) { +- auto box = getGlobalBoundingBox() +- .translate(m_pWindow->m_floatingOffset - pMonitor->m_position) ++void CImgBorder::drawPass( ++ Render::CRenderContext &ctx, PHLMONITOR pMonitor, const float &a, ++ const Render::SWindowRenderPresentation &presentation) { ++ auto box = getGlobalBoundingBox(presentation) ++ .translate(presentation.floatingOffset - pMonitor->m_position) + .scale(pMonitor->m_scale); + + // For debugging +@@ -119,137 +124,84 @@ void CImgBorder::drawPass(PHLMONITOR pMonitor, const float &a) { + + // Save previous values + +- const auto wasUsingNearestNeighbour = +- g_pHyprRenderer->m_renderData.useNearestNeighbor; +- const auto prevUVTL = g_pHyprRenderer->m_renderData.primarySurfaceUVTopLeft; +- const auto prevUVBR = +- g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight; +- +- g_pHyprRenderer->m_renderData.useNearestNeighbor = !m_shouldSmooth; ++ const auto wasUsingNearestNeighbour = ctx.m_data.useNearestNeighbor; ++ const auto prevUVTL = ctx.m_data.primarySurfaceUVTopLeft; ++ const auto prevUVBR = ctx.m_data.primarySurfaceUVBottomRight; ++ ++ ctx.m_data.useNearestNeighbor = !m_shouldSmooth; ++ ++ const auto drawTexture = [&](const SP &texture, ++ const CBox &textureBox, bool repeat = false) { ++ if (!texture) ++ return; ++ ++ g_pHyprRenderer->draw( ++ ctx, ++ CTexPassElement::SRenderData{ ++ .tex = texture, ++ .box = textureBox, ++ .a = a, ++ .blur = shouldBlur(), ++ .allowCustomUV = repeat, ++ .wrapX = repeat ? WRAP_REPEAT : WRAP_CLAMP_TO_EDGE, ++ .wrapY = repeat ? WRAP_REPEAT : WRAP_CLAMP_TO_EDGE, ++ .discardMode = DISCARD_ALPHA, ++ }, ++ CRegion{textureBox}); ++ }; + + // Corners + +- if (m_tex_tl != nullptr) { +- const CBox box_tl = {box.pos(), {BORDER_LEFT, BORDER_TOP}}; +- g_pHyprRenderer->draw({.tex = m_tex_tl, +- .box = box_tl, +- .a = a, +- .damage = box_tl, +- .blur = shouldBlur(), +- .discardMode = DISCARD_ALPHA}); +- } +- +- if (m_tex_tr != nullptr) { +- const CBox box_tr = {{box.x + box.width - BORDER_RIGHT, box.y}, +- {BORDER_RIGHT, BORDER_TOP}}; +- g_pHyprRenderer->draw({.tex = m_tex_tr, +- .box = box_tr, +- .a = a, +- .damage = box_tr, +- .blur = shouldBlur(), +- .discardMode = DISCARD_ALPHA}); +- } +- +- if (m_tex_br != nullptr) { +- const CBox box_br = { +- {box.x + box.width - BORDER_RIGHT, box.y + box.height - BORDER_BOTTOM}, +- {BORDER_RIGHT, BORDER_BOTTOM}}; +- g_pHyprRenderer->draw({.tex = m_tex_br, +- .box = box_br, +- .a = a, +- .damage = box_br, +- .blur = shouldBlur(), +- .discardMode = DISCARD_ALPHA}); +- } +- +- if (m_tex_bl != nullptr) { +- const CBox box_bl = {{box.x, box.y + box.height - BORDER_BOTTOM}, +- {BORDER_LEFT, BORDER_BOTTOM}}; +- g_pHyprRenderer->draw({.tex = m_tex_bl, +- .box = box_bl, +- .a = a, +- .damage = box_bl, +- .blur = shouldBlur(), +- .discardMode = DISCARD_ALPHA}); +- } ++ drawTexture(m_tex_tl, CBox{box.pos(), {BORDER_LEFT, BORDER_TOP}}); ++ drawTexture(m_tex_tr, ++ CBox{{box.x + box.width - BORDER_RIGHT, box.y}, ++ {BORDER_RIGHT, BORDER_TOP}}); ++ drawTexture( ++ m_tex_br, ++ CBox{{box.x + box.width - BORDER_RIGHT, ++ box.y + box.height - BORDER_BOTTOM}, ++ {BORDER_RIGHT, BORDER_BOTTOM}}); ++ drawTexture(m_tex_bl, ++ CBox{{box.x, box.y + box.height - BORDER_BOTTOM}, ++ {BORDER_LEFT, BORDER_BOTTOM}}); + + // Edges + +- g_pHyprRenderer->m_renderData.primarySurfaceUVTopLeft = {0, 0}; +- +- g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight = {1., 1.}; ++ ctx.m_data.primarySurfaceUVTopLeft = {0, 0}; ++ ctx.m_data.primarySurfaceUVBottomRight = {1., 1.}; + if (m_tex_t != nullptr && m_tex_t->m_size.x != 0 && scale != 0) { +- g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight.x = ++ ctx.m_data.primarySurfaceUVBottomRight.x = + WIDTH_MID / (m_tex_t->m_size.x * scale); + } + +- if (m_tex_t != nullptr) { +- const CBox box_t = {{box.x + BORDER_LEFT, box.y}, {WIDTH_MID, BORDER_TOP}}; +- g_pHyprRenderer->draw({.tex = m_tex_t, +- .box = box_t, +- .a = a, +- .damage = box_t, +- .blur = shouldBlur(), +- .allowCustomUV = true, +- .wrapX = WRAP_REPEAT, +- .wrapY = WRAP_REPEAT, +- .discardMode = DISCARD_ALPHA}); +- } +- +- if (m_tex_b != nullptr) { +- const CBox box_b = { +- {box.x + BORDER_LEFT, box.y + box.height - BORDER_BOTTOM}, +- {WIDTH_MID, BORDER_BOTTOM}}; +- g_pHyprRenderer->draw({.tex = m_tex_b, +- .box = box_b, +- .a = a, +- .damage = box_b, +- .blur = shouldBlur(), +- .allowCustomUV = true, +- .wrapX = WRAP_REPEAT, +- .wrapY = WRAP_REPEAT, +- .discardMode = DISCARD_ALPHA}); +- } ++ drawTexture(m_tex_t, ++ CBox{{box.x + BORDER_LEFT, box.y}, {WIDTH_MID, BORDER_TOP}}, ++ true); ++ drawTexture(m_tex_b, ++ CBox{{box.x + BORDER_LEFT, ++ box.y + box.height - BORDER_BOTTOM}, ++ {WIDTH_MID, BORDER_BOTTOM}}, ++ true); + +- g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight = {1., 1.}; ++ ctx.m_data.primarySurfaceUVBottomRight = {1., 1.}; + if (m_tex_l != nullptr && m_tex_l->m_size.y != 0 && scale != 0) { +- g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight.y = ++ ctx.m_data.primarySurfaceUVBottomRight.y = + HEIGHT_MID / (m_tex_l->m_size.y * scale); + } + +- if (m_tex_l != nullptr) { +- const CBox box_l = {{box.x, box.y + BORDER_TOP}, {BORDER_LEFT, HEIGHT_MID}}; +- g_pHyprRenderer->draw({.tex = m_tex_l, +- .box = box_l, +- .a = a, +- .damage = box_l, +- .blur = shouldBlur(), +- .allowCustomUV = true, +- .wrapX = WRAP_REPEAT, +- .wrapY = WRAP_REPEAT, +- .discardMode = DISCARD_ALPHA}); +- } +- +- if (m_tex_r != nullptr) { +- const CBox box_r = {{box.x + box.width - BORDER_RIGHT, box.y + BORDER_TOP}, +- {BORDER_RIGHT, HEIGHT_MID}}; +- g_pHyprRenderer->draw({.tex = m_tex_r, +- .box = box_r, +- .a = a, +- .damage = box_r, +- .blur = shouldBlur(), +- .allowCustomUV = true, +- .wrapX = WRAP_REPEAT, +- .wrapY = WRAP_REPEAT, +- .discardMode = DISCARD_ALPHA}); +- } ++ drawTexture(m_tex_l, ++ CBox{{box.x, box.y + BORDER_TOP}, {BORDER_LEFT, HEIGHT_MID}}, ++ true); ++ drawTexture(m_tex_r, ++ CBox{{box.x + box.width - BORDER_RIGHT, box.y + BORDER_TOP}, ++ {BORDER_RIGHT, HEIGHT_MID}}, ++ true); + + // Restore previous values + +- g_pHyprRenderer->m_renderData.useNearestNeighbor = wasUsingNearestNeighbour; +- +- g_pHyprRenderer->m_renderData.primarySurfaceUVTopLeft = prevUVTL; +- g_pHyprRenderer->m_renderData.primarySurfaceUVBottomRight = prevUVBR; ++ ctx.m_data.useNearestNeighbor = wasUsingNearestNeighbour; ++ ctx.m_data.primarySurfaceUVTopLeft = prevUVTL; ++ ctx.m_data.primarySurfaceUVBottomRight = prevUVBR; + } + + void CImgBorder::updateConfig() { +diff --git a/ImgBorder.hpp b/ImgBorder.hpp +index c0b54f5..969cd15 100644 +--- a/ImgBorder.hpp ++++ b/ImgBorder.hpp +@@ -18,7 +18,8 @@ public: + virtual SDecorationPositioningInfo getPositioningInfo() override; + virtual void + onPositioningReply(const SDecorationPositioningReply &reply) override; +- virtual void draw(PHLMONITOR, float const &a) override; ++ virtual void draw(Render::CRenderContext &, PHLMONITOR, float const &a, ++ const Render::SWindowRenderPresentation &) override; + virtual eDecorationType getDecorationType() override; + virtual void updateWindow(PHLWINDOW) override; + virtual void damageEntire() override; +@@ -30,9 +31,11 @@ public: + + bool shouldBlur(); + +- CBox getGlobalBoundingBox(); ++ CBox getGlobalBoundingBox( ++ const Render::SWindowRenderPresentation &presentation); + +- void drawPass(PHLMONITOR, float const &a); ++ void drawPass(Render::CRenderContext &, PHLMONITOR, float const &a, ++ const Render::SWindowRenderPresentation &presentation); + + void updateConfig(); + void updateRules(); +diff --git a/ImgBorderPassElement.cpp b/ImgBorderPassElement.cpp +index 152c370..93220d8 100644 +--- a/ImgBorderPassElement.cpp ++++ b/ImgBorderPassElement.cpp +@@ -12,14 +12,18 @@ CImgBorderPassElement::CImgBorderPassElement( + } + CImgBorderPassElement::~CImgBorderPassElement() {} + +-std::vector> CImgBorderPassElement::draw() { +- data.deco->drawPass(g_pHyprRenderer->m_renderData.pMonitor.lock(), data.a); ++std::vector> ++CImgBorderPassElement::draw(Render::CRenderContext &ctx) { ++ data.deco->drawPass(ctx, ctx.m_data.pMonitor.lock(), data.a, ++ data.presentation); + return {}; + } + +-bool CImgBorderPassElement::needsLiveBlur() { return data.deco->shouldBlur(); } ++bool CImgBorderPassElement::needsLiveBlur(Render::CRenderContext &ctx) { ++ return data.deco->shouldBlur(); ++} + +-bool CImgBorderPassElement::needsPrecomputeBlur() { ++bool CImgBorderPassElement::needsPrecomputeBlur(Render::CRenderContext &ctx) { + return data.deco->shouldBlur(); + } + +@@ -31,9 +35,11 @@ ePassElementType CImgBorderPassElement::type() { return EK_CUSTOM; } + + // bool CImgBorderPassElement::undiscardable() {} + +-std::optional CImgBorderPassElement::boundingBox() { +- return data.deco->getGlobalBoundingBox().translate( +- -g_pHyprRenderer->m_renderData.pMonitor->m_position); ++std::optional ++CImgBorderPassElement::boundingBox(Render::CRenderContext &ctx) { ++ return data.deco->getGlobalBoundingBox(data.presentation) ++ .translate(data.presentation.floatingOffset - ++ ctx.m_data.pMonitor->m_position); + } + + // CRegion CImgBorderPassElement::opaqueRegion() {} +diff --git a/ImgBorderPassElement.hpp b/ImgBorderPassElement.hpp +index b39475b..c541bab 100644 +--- a/ImgBorderPassElement.hpp ++++ b/ImgBorderPassElement.hpp +@@ -2,6 +2,7 @@ + + #include + #include ++#include + #include + + // Class defined elsewhere +@@ -14,19 +15,22 @@ public: + struct SData { + CImgBorder *deco = nullptr; + float a = 1.F; ++ Render::SWindowRenderPresentation presentation; + }; + + CImgBorderPassElement(const SData &data_); + virtual ~CImgBorderPassElement(); + +- virtual std::vector> draw() override; +- virtual bool needsLiveBlur() override; +- virtual bool needsPrecomputeBlur() override; ++ virtual std::vector> ++ draw(Render::CRenderContext &ctx) override; ++ virtual bool needsLiveBlur(Render::CRenderContext &ctx) override; ++ virtual bool needsPrecomputeBlur(Render::CRenderContext &ctx) override; + virtual const char *passName() override; + virtual ePassElementType type() override; + // virtual void discard() override; + // virtual bool undiscardable() override; +- virtual std::optional boundingBox() override; ++ virtual std::optional ++ boundingBox(Render::CRenderContext &ctx) override; + // virtual CRegion opaqueRegion() override; + // virtual bool disableSimplification() override; + +diff --git a/main.cpp b/main.cpp +index 3934936..32116f5 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -10,7 +10,8 @@ + #include + #include + #include +-#include ++#include ++#include + #include + #include + #include +@@ -24,22 +25,24 @@ APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; } + + static void addToWindow(PHLWINDOW PWINDOW) { + // Create border and apply it +- auto border = makeUnique(PWINDOW); ++ auto border = makeShared(PWINDOW); + border->m_self = border; + g_pGlobalState->borders.emplace_back(border); + HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, std::move(border)); + } + + static void onWindowOpen(PHLWINDOW window) { +- if (!window->m_X11DoesntWantBorders) { +- // Make sure we haven't added the border already +- if (std::ranges::any_of(window->m_windowDecorations, [](const auto &d) { +- return d->getDisplayName() == DISPLAY_NAME; +- })) +- return; +- +- addToWindow(window); +- } ++ if (window->backend().traits().suggestsNoBorder) ++ return; ++ ++ // Make sure we haven't added the border already ++ if (std::ranges::any_of(window->presentation().decorations(), ++ [](const auto &d) { ++ return d->getDisplayName() == DISPLAY_NAME; ++ })) ++ return; ++ ++ addToWindow(window); + } + + static void onWindowClose(PHLWINDOW window) { +@@ -51,7 +54,7 @@ static void onWindowClose(PHLWINDOW window) { + return; + + // We could use the API but this is faster + it doesn't matter here that much. +- window->removeWindowDeco(BORDER->get()); ++ window->presentation().removeDecoration(BORDER->get()); + } + + static void onWindowUpdateRules(PHLWINDOW window) { +@@ -63,7 +66,7 @@ static void onWindowUpdateRules(PHLWINDOW window) { + return; + + (*BORDER)->updateRules(); +- window->updateWindowDecos(); ++ window->presentation().updateDecorations(); + } + + static void onConfigReloaded() { +@@ -131,7 +134,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { + + // Add to existing windows + for (auto &w : Desktop::windowState()->windows()) { +- if (w->isHidden() || !w->m_isMapped) ++ if (w->isHidden() || !w->mapped()) + continue; + addToWindow(w); + } +@@ -143,7 +146,7 @@ APICALL EXPORT void PLUGIN_EXIT() { + for (auto &m : State::monitorState()->monitors()) + m->m_scheduledRecalc = true; + +- g_pHyprRenderer->m_renderPass.removeAllOfType(PASS_NAME); ++ g_pHyprRenderer->context().m_pass.removeAllOfType(PASS_NAME); + + // Unregister window rules + Desktop::Rule::windowEffects()->unregisterEffect( diff --git a/fedora/packages/rpm/fetch/imgborders.sh b/fedora/packages/rpm/fetch/imgborders.sh index a9ee5ec373..7ae4afaa6e 100755 --- a/fedora/packages/rpm/fetch/imgborders.sh +++ b/fedora/packages/rpm/fetch/imgborders.sh @@ -5,17 +5,14 @@ set -euo pipefail package=imgborders dest="$RYOKU_FETCH_TREE/.rpm-$package/$package" bundle="$RYOKU_FETCH_TREE/release/packages/$package/$package.bundle" +patch="$RYOKU_FETCH_TREE/fedora/packages/rpm/fetch/imgborders-hyprland-0.57.patch" +commit=08be22236144d3c91607bcfa955ed0d457f4f50b rm -rf "$dest" mkdir -p "${dest%/*}" git clone -q "$bundle" "$dest" -hyprland_version=$(pkg-config --modversion hyprland) -commit=$(grep -F "$hyprland_version" "$dest/hyprpm.toml" | grep -oE '[0-9a-f]{40}' | sed -n '2p' || true) -if [[ -z $commit ]]; then - commit=$(git -C "$dest" rev-parse HEAD) -fi -[[ $commit =~ ^[0-9a-f]{40}$ ]] git -C "$dest" checkout -q --detach "$commit" [[ $(git -C "$dest" rev-parse HEAD) == "$commit" ]] +git -C "$dest" apply "$patch" printf '%s\n' "$commit" > "$dest/.ryoku-source-commit" rm -rf "$dest/.git" diff --git a/release/CHANGELOG.md b/release/CHANGELOG.md index 2837b44520..8af622b3cc 100644 --- a/release/CHANGELOG.md +++ b/release/CHANGELOG.md @@ -152,6 +152,15 @@ the other plugin packages. ### Fixed +- **Fedora builds the image-border plugin against Hyprland 0.57.** Fedora moved + `hyprland-devel` to 0.57, whose renderer passes an explicit + `CRenderContext` and dropped the `m_renderData` field the plugin read, so the + RPM build failed and held the whole Fedora publish. The vendored bundle now + carries upstream's current commit plus a Ryoku port of the plugin to the + 0.57 API (applied by the Fedora fetch hook only; the Arch lane keeps its + 0.56 source pin and is unchanged), proven to link `libimgborders.so` in + Fedora 44 and 45 containers (`fedora/packages/rpm/fetch/`, + `release/packages/imgborders/`). - **Hyprland screen sharing survives DMA-BUF renegotiation.** `[ryoku]` now carries the post-1.4.1 portal fixes that preserve the capture callback and bound PipeWire stream startup instead of wedging every later share. diff --git a/release/packages/imgborders/PKGBUILD b/release/packages/imgborders/PKGBUILD index 99f379dcb6..847f2c72f3 100644 --- a/release/packages/imgborders/PKGBUILD +++ b/release/packages/imgborders/PKGBUILD @@ -37,7 +37,7 @@ depends=('hyprland') makedepends=('hyprland' 'cmake' 'pkgconf' 'git' 'libdrm' 'pixman' 'pango' 'cairo') source=("$pkgname.bundle") noextract=("$pkgname.bundle") -sha256sums=('48187e72ca62fc0b8d12809ca02082b8d27016516d84527a19abb3ff007d6a7d') +sha256sums=('8d40c70536a44364c9e9aec9cd69321b5e6880df1b76c7f11b7839ecc645d6c4') # the plugin ABI this build locks to, Hyprland's own client-hash formula: # commit + major.minor of aquamarine, hyprutils, hyprgraphics, hyprcursor and diff --git a/release/packages/imgborders/imgborders.bundle b/release/packages/imgborders/imgborders.bundle index 734d2e00df63047068dcec723fcdab0537c65dba..ebf33ac5528a2b2fab654850704bb4b9d4a92bbd 100644 GIT binary patch delta 11833 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 lPlr@8&#jPJ@Gm;9d@cY0