From 9c38287410b305503f921e411eb39686b23ccc42 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 31 Jan 2025 13:32:36 +0000 Subject: [PATCH] groupbar: various visual improvements added rounding, round at edges, and indicator height --- src/config/ConfigDescriptions.hpp | 32 ++++++- src/config/ConfigManager.cpp | 7 +- .../decorations/CHyprGroupBarDecoration.cpp | 91 +++++++++++++++---- src/render/pass/RectPassElement.cpp | 5 + src/render/pass/RectPassElement.hpp | 1 + src/render/pass/TexPassElement.cpp | 6 +- src/render/pass/TexPassElement.hpp | 1 + 7 files changed, 121 insertions(+), 22 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 483f1f1f..01ef392e 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -883,7 +883,7 @@ inline static const std::vector CONFIG_OPTIONS = { .value = "group:groupbar:gradients", .description = "enables gradients", .type = CONFIG_OPTION_BOOL, - .data = SConfigOptionDescription::SBoolData{true}, + .data = SConfigOptionDescription::SBoolData{false}, }, SConfigOptionDescription{ .value = "group:groupbar:height", @@ -891,6 +891,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{14, 1, 64}, }, + SConfigOptionDescription{ + .value = "group:groupbar:indicator_height", + .description = "height of the groupbar indicator", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{3, 1, 64}, + }, SConfigOptionDescription{ .value = "group:groupbar:stacked", .description = "render the groupbar as a vertical stack", @@ -915,6 +921,30 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{true}, }, + SConfigOptionDescription{ + .value = "group:groupbar:rounding", + .description = "how much to round the groupbar", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{1, 0, 20}, + }, + SConfigOptionDescription{ + .value = "group:groupbar:gradient_rounding", + .description = "how much to round the groupbar gradient", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{1, 0, 20}, + }, + SConfigOptionDescription{ + .value = "group:groupbar:round_only_edges", + .description = "if yes, will only round at the groupbar edges", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, + SConfigOptionDescription{ + .value = "group:groupbar:groupbar_round_only_edges", + .description = "if yes, will only round at the groupbar gradient edges", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, SConfigOptionDescription{ .value = "group:groupbar:text_color", .description = "controls the group bar text color", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 86581b10..e36a2914 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -441,13 +441,18 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY}); m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8}); - m_pConfig->addConfigValue("group:groupbar:gradients", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:groupbar:gradients", Hyprlang::INT{0}); m_pConfig->addConfigValue("group:groupbar:height", Hyprlang::INT{14}); + m_pConfig->addConfigValue("group:groupbar:indicator_height", Hyprlang::INT{3}); m_pConfig->addConfigValue("group:groupbar:priority", Hyprlang::INT{3}); m_pConfig->addConfigValue("group:groupbar:render_titles", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:scrolling", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:text_color", Hyprlang::INT{0xffffffff}); m_pConfig->addConfigValue("group:groupbar:stacked", Hyprlang::INT{0}); + m_pConfig->addConfigValue("group:groupbar:rounding", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:groupbar:gradient_rounding", Hyprlang::INT{2}); + m_pConfig->addConfigValue("group:groupbar:round_only_edges", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:groupbar:gradient_round_only_edges", Hyprlang::INT{1}); m_pConfig->addConfigValue("debug:int", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:log_damage", Hyprlang::INT{0}); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 88501d74..1a64b024 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -15,7 +15,6 @@ static SP m_tGradientInactive = makeShared(); static SP m_tGradientLockedActive = makeShared(); static SP m_tGradientLockedInactive = makeShared(); -constexpr int BAR_INDICATOR_HEIGHT = 3; constexpr int BAR_PADDING_OUTER_VERT = 2; constexpr int BAR_PADDING_OUTER_HORZ = 2; constexpr int BAR_TEXT_PAD = 2; @@ -30,12 +29,13 @@ CHyprGroupBarDecoration::CHyprGroupBarDecoration(PHLWINDOW pWindow) : IHyprWindo } SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() { - static auto PHEIGHT = CConfigValue("group:groupbar:height"); - static auto PENABLED = CConfigValue("group:groupbar:enabled"); - static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); - static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); - static auto PPRIORITY = CConfigValue("group:groupbar:priority"); - static auto PSTACKED = CConfigValue("group:groupbar:stacked"); + static auto PHEIGHT = CConfigValue("group:groupbar:height"); + static auto PINDICATORHEIGHT = CConfigValue("group:groupbar:indicator_height"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); + static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); + static auto PPRIORITY = CConfigValue("group:groupbar:priority"); + static auto PSTACKED = CConfigValue("group:groupbar:stacked"); SDecorationPositioningInfo info; info.policy = DECORATION_POSITION_STICKY; @@ -45,10 +45,10 @@ SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() { if (*PENABLED && m_pWindow->m_sWindowData.decorate.valueOrDefault()) { if (*PSTACKED) { - const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); + const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); info.desiredExtents = {{0, (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT}, {0, 0}}; } else - info.desiredExtents = {{0, BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2}, {0, 0}}; + info.desiredExtents = {{0, BAR_PADDING_OUTER_VERT * 2 + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2}, {0, 0}}; } else info.desiredExtents = {{0, 0}, {0, 0}}; return info; @@ -99,19 +99,24 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { // get how many bars we will draw int barsToDraw = m_dwGroupMembers.size(); - static auto PENABLED = CConfigValue("group:groupbar:enabled"); - static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); - static auto PTITLEFONTSIZE = CConfigValue("group:groupbar:font_size"); - static auto PHEIGHT = CConfigValue("group:groupbar:height"); - static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); - static auto PSTACKED = CConfigValue("group:groupbar:stacked"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); + static auto PTITLEFONTSIZE = CConfigValue("group:groupbar:font_size"); + static auto PHEIGHT = CConfigValue("group:groupbar:height"); + static auto PINDICATORHEIGHT = CConfigValue("group:groupbar:indicator_height"); + static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); + static auto PSTACKED = CConfigValue("group:groupbar:stacked"); + static auto PROUNDING = CConfigValue("group:groupbar:rounding"); + static auto PGRADIENTROUNDING = CConfigValue("group:groupbar:gradient_rounding"); + static auto PGRADIENTROUNDINGONLYEDGES = CConfigValue("group:groupbar:gradient_round_only_edges"); + static auto PROUNDONLYEDGES = CConfigValue("group:groupbar:round_only_edges"); if (!*PENABLED || !m_pWindow->m_sWindowData.decorate.valueOrDefault()) return; const auto ASSIGNEDBOX = assignedBoxGlobal(); - const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); + const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); m_fBarWidth = *PSTACKED ? ASSIGNEDBOX.w : (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw; m_fBarHeight = *PSTACKED ? ((ASSIGNEDBOX.h - 2 - BAR_PADDING_OUTER_VERT) - BAR_PADDING_OUTER_VERT * (barsToDraw)) / barsToDraw : ASSIGNEDBOX.h - BAR_PADDING_OUTER_VERT; @@ -126,8 +131,8 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { const auto WINDOWINDEX = *PSTACKED ? m_dwGroupMembers.size() - i - 1 : i; CBox rect = {ASSIGNEDBOX.x + floor(xoff) - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, - ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, - m_fBarWidth, BAR_INDICATOR_HEIGHT}; + ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - *PINDICATORHEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, + m_fBarWidth, *PINDICATORHEIGHT}; if (rect.width <= 0 || rect.height <= 0) break; @@ -152,6 +157,30 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { CRectPassElement::SRectData rectdata; rectdata.color = color; rectdata.box = rect; + if (*PROUNDING) { + if (*PROUNDONLYEDGES) { + static constexpr double PADDING = 20; + + if (i == 0 && barsToDraw == 1) + rectdata.round = *PROUNDING; + else if (i == 0) { + double first = rect.w - (*PROUNDING * 2); + rectdata.round = *PROUNDING; + rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); + rectdata.round = 0; + rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } else if (i == barsToDraw - 1) { + double first = *PROUNDING * 2; + rectdata.round = 0; + rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); + rectdata.round = *PROUNDING; + rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } + } else + rectdata.round = *PROUNDING; + } g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); rect = {ASSIGNEDBOX.x + floor(xoff) - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, @@ -166,6 +195,30 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { CTexPassElement::SRenderData data; data.tex = GRADIENTTEX; data.box = rect; + if (*PGRADIENTROUNDING) { + if (*PGRADIENTROUNDINGONLYEDGES) { + static constexpr double PADDING = 20; + + if (i == 0 && barsToDraw == 1) + data.round = *PGRADIENTROUNDING; + else if (i == 0) { + double first = rect.w - (*PGRADIENTROUNDING * 2); + data.round = *PGRADIENTROUNDING; + data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + data.round = 0; + data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } else if (i == barsToDraw - 1) { + double first = *PGRADIENTROUNDING * 2; + data.round = 0; + data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + data.round = *PGRADIENTROUNDING; + data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } + } else + rectdata.round = *PGRADIENTROUNDING; + } g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } } @@ -229,7 +282,7 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float texSize = tex->m_vSize; } -void renderGradientTo(SP tex, CGradientValueData* grad) { +static void renderGradientTo(SP tex, CGradientValueData* grad) { if (!g_pCompositor->m_pLastMonitor) return; diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index fba06286..aa024577 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -9,10 +9,15 @@ void CRectPassElement::draw(const CRegion& damage) { if (data.box.w <= 0 || data.box.h <= 0) return; + if (!data.clipBox.empty()) + g_pHyprOpenGL->m_RenderData.clipBox = data.clipBox; + if (data.color.a == 1.F || !data.blur) g_pHyprOpenGL->renderRectWithDamage(data.box, data.color, damage, data.round, data.roundingPower); else g_pHyprOpenGL->renderRectWithBlur(data.box, data.color, data.round, data.roundingPower, data.blurA, data.xray); + + g_pHyprOpenGL->m_RenderData.clipBox = {}; } bool CRectPassElement::needsLiveBlur() { diff --git a/src/render/pass/RectPassElement.hpp b/src/render/pass/RectPassElement.hpp index d27abdcc..f798dbf9 100644 --- a/src/render/pass/RectPassElement.hpp +++ b/src/render/pass/RectPassElement.hpp @@ -10,6 +10,7 @@ class CRectPassElement : public IPassElement { float roundingPower = 2.0f; bool blur = false, xray = false; float blurA = 1.F; + CBox clipBox; }; CRectPassElement(const SRectData& data); diff --git a/src/render/pass/TexPassElement.cpp b/src/render/pass/TexPassElement.cpp index c7eab292..8b577373 100644 --- a/src/render/pass/TexPassElement.cpp +++ b/src/render/pass/TexPassElement.cpp @@ -13,9 +13,13 @@ void CTexPassElement::draw(const CRegion& damage) { CScopeGuard x = {[]() { // - g_pHyprOpenGL->m_bEndFrame = false; + g_pHyprOpenGL->m_bEndFrame = false; + g_pHyprOpenGL->m_RenderData.clipBox = {}; }}; + if (!data.clipBox.empty()) + g_pHyprOpenGL->m_RenderData.clipBox = data.clipBox; + if (data.replaceProjection) g_pHyprOpenGL->m_RenderData.monitorProjection = *data.replaceProjection; g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.roundingPower, data.syncTimeline, diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp index 036b89fe..6faa0872 100644 --- a/src/render/pass/TexPassElement.hpp +++ b/src/render/pass/TexPassElement.hpp @@ -19,6 +19,7 @@ class CTexPassElement : public IPassElement { SP syncTimeline; int64_t syncPoint = 0; std::optional replaceProjection; + CBox clipBox; }; CTexPassElement(const SRenderData& data);