From 4b0d8a0eff2613b9a330be216de16bea13fd9862 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 27 Feb 2023 15:24:28 +0000 Subject: [PATCH] Added borders-plus-plus --- borders-plus-plus/Makefile | 8 +++ borders-plus-plus/README.md | 16 +++++ borders-plus-plus/borderDeco.cpp | 105 +++++++++++++++++++++++++++++++ borders-plus-plus/borderDeco.hpp | 29 +++++++++ borders-plus-plus/globals.hpp | 5 ++ borders-plus-plus/main.cpp | 47 ++++++++++++++ 6 files changed, 210 insertions(+) create mode 100644 borders-plus-plus/Makefile create mode 100644 borders-plus-plus/README.md create mode 100644 borders-plus-plus/borderDeco.cpp create mode 100644 borders-plus-plus/borderDeco.hpp create mode 100644 borders-plus-plus/globals.hpp create mode 100644 borders-plus-plus/main.cpp diff --git a/borders-plus-plus/Makefile b/borders-plus-plus/Makefile new file mode 100644 index 0000000..3866c3c --- /dev/null +++ b/borders-plus-plus/Makefile @@ -0,0 +1,8 @@ +# compile with HYPRLAND_HEADERS= make all +# make sure that the path above is to the root hl repo directory, NOT src/ +# and that you have ran `make protocols` in the hl dir. + +all: + g++ -shared -fPIC --no-gnu-unique main.cpp borderDeco.cpp -o borders-plus-plus.so -g -I "/usr/include/pixman-1" -I "/usr/include/libdrm" -I "${HYPRLAND_HEADERS}" -std=c++23 +clean: + rm ./borders-plus-plus.so diff --git a/borders-plus-plus/README.md b/borders-plus-plus/README.md new file mode 100644 index 0000000..0f70adc --- /dev/null +++ b/borders-plus-plus/README.md @@ -0,0 +1,16 @@ +# borders-plus-plus + +Allows you to add one or two additional borders to your windows. + +The borders added are static. + +Config: +``` +plugins { + borders-plus-plus { + add_borders = 1 # 0 - 2 + col.border_1 = rgb(ffffff) # example col for border 1 + col.border_2 = rgb(2222ff) # example col for border 2 + } +} +``` \ No newline at end of file diff --git a/borders-plus-plus/borderDeco.cpp b/borders-plus-plus/borderDeco.cpp new file mode 100644 index 0000000..81b118e --- /dev/null +++ b/borders-plus-plus/borderDeco.cpp @@ -0,0 +1,105 @@ +#include "borderDeco.hpp" +#include "globals.hpp" +#include +#include + +CBordersPlusPlus::CBordersPlusPlus(CWindow* pWindow) { + m_pWindow = pWindow; + m_vLastWindowPos = pWindow->m_vRealPosition.vec(); + m_vLastWindowSize = pWindow->m_vRealSize.vec(); +} + +CBordersPlusPlus::~CBordersPlusPlus() { + damageEntire(); +} + +SWindowDecorationExtents CBordersPlusPlus::getWindowDecorationExtents() { + return m_seExtents; +} + +void CBordersPlusPlus::draw(CMonitor* pMonitor, float a, const Vector2D& offset) { + if (!g_pCompositor->windowValidMapped(m_pWindow)) + return; + + if (!m_pWindow->m_sSpecialRenderData.decorate) + return; + + static auto* const PCOLOR1 = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:borders-plus-plus:col.border_1")->intValue; + static auto* const PCOLOR2 = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:borders-plus-plus:col.border_2")->intValue; + static auto* const PBORDERS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:borders-plus-plus:add_borders")->intValue; + static auto* const PROUNDING = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue; + static auto* const PBORDERSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue; + + if (*PBORDERS < 1) + return; + + const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? + 0 : + (m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying()); + + // draw the border + wlr_box fullBox = { (int)(m_vLastWindowPos.x - *PBORDERSIZE), (int)(m_vLastWindowPos.y - *PBORDERSIZE), (int)(m_vLastWindowSize.x + 2.0 * *PBORDERSIZE), (int)(m_vLastWindowSize.y + 2.0 * *PBORDERSIZE) }; + + fullBox.x -= pMonitor->vecPosition.x; + fullBox.y -= pMonitor->vecPosition.y; + + m_seExtents = { { m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2 }, + { fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2, + fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2 } }; + + fullBox.x += offset.x; + fullBox.y += offset.y; + + if (fullBox.width < 1 || fullBox.height < 1) + return; // don't draw invisible shadows + + g_pHyprOpenGL->scissor((wlr_box*)nullptr); + + scaleBox(&fullBox, pMonitor->scale); + g_pHyprOpenGL->renderBorder(&fullBox, CColor(*PCOLOR1), *PROUNDING * pMonitor->scale + *PBORDERSIZE * 2, a); + + // pass 2 + + if (*PBORDERS < 2) + return; + + fullBox = { (int)(m_vLastWindowPos.x - *PBORDERSIZE * 2), (int)(m_vLastWindowPos.y - *PBORDERSIZE * 2), (int)(m_vLastWindowSize.x + 2.0 * *PBORDERSIZE * 2), (int)(m_vLastWindowSize.y + 2.0 * *PBORDERSIZE * 2) }; + + scaleBox(&fullBox, pMonitor->scale); + g_pHyprOpenGL->renderBorder(&fullBox, CColor(*PCOLOR1), *PROUNDING * pMonitor->scale + *PBORDERSIZE * 2, a); + + fullBox.x -= pMonitor->vecPosition.x; + fullBox.y -= pMonitor->vecPosition.y; + + m_seExtents = { { m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2 }, + { fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2, + fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2 } }; + + fullBox.x += offset.x; + fullBox.y += offset.y; + + if (fullBox.width < 1 || fullBox.height < 1) + return; // don't draw invisible shadows + + g_pHyprOpenGL->scissor((wlr_box*)nullptr); + + scaleBox(&fullBox, pMonitor->scale); + g_pHyprOpenGL->renderBorder(&fullBox, CColor(*PCOLOR2), *PROUNDING * pMonitor->scale + *PBORDERSIZE * 2, a); +} + +eDecorationType CBordersPlusPlus::getDecorationType() { + return DECORATION_CUSTOM; +} + +void CBordersPlusPlus::updateWindow(CWindow* pWindow) { + + m_vLastWindowPos = pWindow->m_vRealPosition.vec(); + m_vLastWindowSize = pWindow->m_vRealSize.vec(); + + damageEntire(); +} + +void CBordersPlusPlus::damageEntire() { + wlr_box dm = { (int)(m_vLastWindowPos.x - m_seExtents.topLeft.x), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y), (int)(m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x), (int)m_seExtents.topLeft.y }; + g_pHyprRenderer->damageBox(&dm); +} \ No newline at end of file diff --git a/borders-plus-plus/borderDeco.hpp b/borders-plus-plus/borderDeco.hpp new file mode 100644 index 0000000..c847386 --- /dev/null +++ b/borders-plus-plus/borderDeco.hpp @@ -0,0 +1,29 @@ +#pragma once + +#define WLR_USE_UNSTABLE + +#include + +class CBordersPlusPlus : public IHyprWindowDecoration { + public: + CBordersPlusPlus(CWindow*); + virtual ~CBordersPlusPlus(); + + virtual SWindowDecorationExtents getWindowDecorationExtents(); + + virtual void draw(CMonitor*, float a, const Vector2D& offset); + + virtual eDecorationType getDecorationType(); + + virtual void updateWindow(CWindow*); + + virtual void damageEntire(); + + private: + SWindowDecorationExtents m_seExtents; + + CWindow* m_pWindow = nullptr; + + Vector2D m_vLastWindowPos; + Vector2D m_vLastWindowSize; +}; \ No newline at end of file diff --git a/borders-plus-plus/globals.hpp b/borders-plus-plus/globals.hpp new file mode 100644 index 0000000..37e8363 --- /dev/null +++ b/borders-plus-plus/globals.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include + +inline HANDLE PHANDLE = nullptr; \ No newline at end of file diff --git a/borders-plus-plus/main.cpp b/borders-plus-plus/main.cpp new file mode 100644 index 0000000..e66caa7 --- /dev/null +++ b/borders-plus-plus/main.cpp @@ -0,0 +1,47 @@ +#define WLR_USE_UNSTABLE + +#include + +#include +#include +#include +#include + +#include "borderDeco.hpp" +#include "globals.hpp" + +// Do NOT change this function. +APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; } + +void onNewWindow(void* self, std::any data) { + // data is guaranteed + auto* const PWINDOW = std::any_cast(data); + + HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CBordersPlusPlus(PWINDOW)); +} + +APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { + PHANDLE = handle; + + HyprlandAPI::addConfigValue(PHANDLE, "plugin:borders-plus-plus:add_borders", SConfigValue { .intValue = 1 }); + HyprlandAPI::addConfigValue(PHANDLE, "plugin:borders-plus-plus:col.border_1", SConfigValue { .intValue = configStringToInt("rgba(000000ee)") }); + HyprlandAPI::addConfigValue(PHANDLE, "plugin:borders-plus-plus:col.border_2", SConfigValue { .intValue = configStringToInt("rgba(000000ee)") }); + + HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, std::any data) { onNewWindow(self, data); }); + + // add deco to existing windows + for (auto& w : g_pCompositor->m_vWindows) { + if (w->isHidden() || !w->m_bIsMapped) + continue; + + HyprlandAPI::addWindowDecoration(PHANDLE, w.get(), new CBordersPlusPlus(w.get())); + } + + HyprlandAPI::reloadConfig(); + + HyprlandAPI::addNotification(PHANDLE, "[borders-plus-plus] Initialized successfully!", CColor { 0.2, 1.0, 0.2, 1.0 }, 5000); + + return { "borders-plus-plus", "A plugin to add more borders to windows.", "Vaxry", "1.0" }; +} + +APICALL EXPORT void PLUGIN_EXIT() { ; } \ No newline at end of file