diff --git a/hyprbars/README.md b/hyprbars/README.md index 89abc21..7c7d4c4 100644 --- a/hyprbars/README.md +++ b/hyprbars/README.md @@ -58,4 +58,6 @@ hyprbars-button = color, size, icon, on-click Hyprbars supports the following _dynamic_ window rules: -`plugin:hyprbars:nobar` -> disables the bar on matching windows. \ No newline at end of file +`plugin:hyprbars:nobar` -> disables the bar on matching windows. +`plugin:hyprbars:bar_color` -> sets the bar background color on matching windows. +`plugin:hyprbars:title_color` -> sets the bar title color on matching windows. diff --git a/hyprbars/barDeco.cpp b/hyprbars/barDeco.cpp index 7de61a4..0cc7514 100644 --- a/hyprbars/barDeco.cpp +++ b/hyprbars/barDeco.cpp @@ -18,7 +18,7 @@ CHyprBar::CHyprBar(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow) { m_pMouseMoveCallback = HyprlandAPI::registerCallbackDynamic(PHANDLE, "mouseMove", [&](void* self, SCallbackInfo& info, std::any param) { onMouseMove(std::any_cast(param)); }); - m_pTextTex = makeShared(); + m_pTextTex = makeShared(); m_pButtonsTex = makeShared(); } @@ -220,7 +220,7 @@ void CHyprBar::renderBarTitle(const Vector2D& bufferSize, const float scale) { const auto scaledButtonsPad = **PBARBUTTONPADDING * scale; const auto scaledBarPadding = **PBARPADDING * scale; - const CColor COLOR = **PCOLOR; + const CColor COLOR = m_bForcedTitleColor.value_or(**PCOLOR); const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y); const auto CAIRO = cairo_create(CAIROSURFACE); @@ -412,7 +412,7 @@ void CHyprBar::draw(CMonitor* pMonitor, float a) { const auto scaledRounding = ROUNDING > 0 ? ROUNDING * pMonitor->scale - 2 /* idk why but otherwise it looks bad due to the gaps */ : 0; - CColor color = **PCOLOR; + CColor color = m_bForcedBarColor.value_or(**PCOLOR); color.a *= a; m_seExtents = {{0, **PHEIGHT}, {}}; @@ -461,7 +461,7 @@ void CHyprBar::draw(CMonitor* pMonitor, float a) { g_pHyprOpenGL->renderRect(&titleBarBox, color, scaledRounding); // render title - if (**PENABLETITLE && (m_szLastTitle != PWINDOW->m_szTitle || m_bWindowSizeChanged || m_pTextTex->m_iTexID == 0)) { + if (**PENABLETITLE && (m_szLastTitle != PWINDOW->m_szTitle || m_bWindowSizeChanged || m_pTextTex->m_iTexID == 0 || m_bTitleColorChanged)) { m_szLastTitle = PWINDOW->m_szTitle; renderBarTitle(BARBUF, pMonitor->scale); } @@ -491,6 +491,7 @@ void CHyprBar::draw(CMonitor* pMonitor, float a) { renderBarButtonsText(&textBox, pMonitor->scale, a); m_bWindowSizeChanged = false; + m_bTitleColorChanged = false; // dynamic updates change the extents if (m_iLastHeight != **PHEIGHT) { @@ -540,11 +541,33 @@ PHLWINDOW CHyprBar::getOwner() { return m_pWindow.lock(); } -void CHyprBar::setHidden(bool hidden) { - if (m_bHidden == hidden) - return; +void CHyprBar::updateRules() { + const auto PWINDOW = m_pWindow.lock(); + auto rules = PWINDOW->m_vMatchedRules; + auto prev_m_bHidden = m_bHidden; + auto prev_m_bForcedTitleColor = m_bForcedTitleColor; - m_bHidden = hidden; + m_bForcedBarColor = std::nullopt; + m_bForcedTitleColor = std::nullopt; + m_bHidden = false; - g_pDecorationPositioner->repositionDeco(this); + for (auto& r : rules) { + applyRule(r); + } + + if (prev_m_bHidden != m_bHidden) + g_pDecorationPositioner->repositionDeco(this); + if (prev_m_bForcedTitleColor != m_bForcedTitleColor) + m_bTitleColorChanged = true; +} + +void CHyprBar::applyRule(const SWindowRule& r) { + auto arg = r.szRule.substr(r.szRule.find_first_of(' ') + 1); + + if (r.szRule == "plugin:hyprbars:nobar") + m_bHidden = true; + else if (r.szRule.starts_with("plugin:hyprbars:bar_color")) + m_bForcedBarColor = CColor(configStringToInt(arg)); + else if (r.szRule.starts_with("plugin:hyprbars:title_color")) + m_bForcedTitleColor = CColor(configStringToInt(arg)); } diff --git a/hyprbars/barDeco.hpp b/hyprbars/barDeco.hpp index 0c4fb12..c75d0ec 100644 --- a/hyprbars/barDeco.hpp +++ b/hyprbars/barDeco.hpp @@ -34,39 +34,43 @@ class CHyprBar : public IHyprWindowDecoration { PHLWINDOW getOwner(); - void setHidden(bool hidden); + void updateRules(); + void applyRule(const SWindowRule&); private: - SBoxExtents m_seExtents; + SBoxExtents m_seExtents; - PHLWINDOWREF m_pWindow; + PHLWINDOWREF m_pWindow; - CBox m_bAssignedBox; + CBox m_bAssignedBox; - SP m_pTextTex; - SP m_pButtonsTex; + SP m_pTextTex; + SP m_pButtonsTex; - bool m_bWindowSizeChanged = false; - bool m_bHidden = false; + bool m_bWindowSizeChanged = false; + bool m_bHidden = false; + bool m_bTitleColorChanged = false; + std::optional m_bForcedBarColor; + std::optional m_bForcedTitleColor; - Vector2D cursorRelativeToBar(); + Vector2D cursorRelativeToBar(); - void renderBarTitle(const Vector2D& bufferSize, const float scale); - void renderText(SP out, const std::string& text, const CColor& color, const Vector2D& bufferSize, const float scale, const int fontSize); - void renderBarButtons(const Vector2D& bufferSize, const float scale); - void renderBarButtonsText(CBox* barBox, const float scale, const float a); - void onMouseDown(SCallbackInfo& info, IPointer::SButtonEvent e); - void onMouseMove(Vector2D coords); - CBox assignedBoxGlobal(); + void renderBarTitle(const Vector2D& bufferSize, const float scale); + void renderText(SP out, const std::string& text, const CColor& color, const Vector2D& bufferSize, const float scale, const int fontSize); + void renderBarButtons(const Vector2D& bufferSize, const float scale); + void renderBarButtonsText(CBox* barBox, const float scale, const float a); + void onMouseDown(SCallbackInfo& info, IPointer::SButtonEvent e); + void onMouseMove(Vector2D coords); + CBox assignedBoxGlobal(); - SP m_pMouseButtonCallback; - SP m_pMouseMoveCallback; + SP m_pMouseButtonCallback; + SP m_pMouseMoveCallback; - std::string m_szLastTitle; + std::string m_szLastTitle; - bool m_bDraggingThis = false; - bool m_bDragPending = false; - bool m_bCancelledDown = false; + bool m_bDraggingThis = false; + bool m_bDragPending = false; + bool m_bCancelledDown = false; // for dynamic updates int m_iLastHeight = 0; diff --git a/hyprbars/main.cpp b/hyprbars/main.cpp index 060f1a5..7d58476 100644 --- a/hyprbars/main.cpp +++ b/hyprbars/main.cpp @@ -49,9 +49,8 @@ static void onUpdateWindowRules(PHLWINDOW window) { if (BARIT == g_pGlobalState->bars.end()) return; - const auto HASNOBAR = std::find_if(window->m_vMatchedRules.begin(), window->m_vMatchedRules.end(), [](const auto& rule) { return rule.szRule == "plugin:hyprbars:nobar"; }) != window->m_vMatchedRules.end(); - - (*BARIT)->setHidden(HASNOBAR); + (*BARIT)->updateRules(); + window->updateWindowDecos(); } Hyprlang::CParseResult onNewButton(const char* K, const char* V) {