aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIsaac Myhal <[email protected]>2024-01-14 12:27:32 -0500
committerGitHub <[email protected]>2024-01-14 18:27:32 +0100
commitb6516bad0281efb55195e8db180aa2dcaf8b98e4 (patch)
treed51812e9eda1badd0782bc764afb9777da462537
parent13d9a637d61ffdd0cb23dda80f6a971f17e0f5b3 (diff)
downloadHyprland-b6516bad0281efb55195e8db180aa2dcaf8b98e4.tar.gz
Hyprland-b6516bad0281efb55195e8db180aa2dcaf8b98e4.zip
config: Add border gradients to windowrulev2 (#4335)
* Add border gradients to windowrulev2 * windowrule border gradient: Use CVarList to parse * windowrule border gradient: No {} around short ifs
-rw-r--r--src/Compositor.cpp10
-rw-r--r--src/Window.cpp48
-rw-r--r--src/Window.hpp12
-rw-r--r--src/config/ConfigDataValues.hpp1
-rw-r--r--src/debug/HyprCtl.cpp4
5 files changed, 51 insertions, 24 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 2b3fc7d3..b37e25b2 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -1884,15 +1884,13 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
if (pWindow == m_pLastWindow) {
const auto* const ACTIVECOLOR =
!pWindow->m_sGroupData.pNextWindow ? (!pWindow->m_sGroupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
- setBorderColor(pWindow->m_sSpecialRenderData.activeBorderColor.toUnderlying() >= 0 ?
- CGradientValueData(CColor(pWindow->m_sSpecialRenderData.activeBorderColor.toUnderlying())) :
- *ACTIVECOLOR);
+ setBorderColor(pWindow->m_sSpecialRenderData.activeBorderColor.toUnderlying().m_vColors.empty() ? *ACTIVECOLOR :
+ pWindow->m_sSpecialRenderData.activeBorderColor.toUnderlying());
} else {
const auto* const INACTIVECOLOR =
!pWindow->m_sGroupData.pNextWindow ? (!pWindow->m_sGroupData.deny ? INACTIVECOL : NOGROUPINACTIVECOL) : (GROUPLOCKED ? GROUPINACTIVELOCKEDCOL : GROUPINACTIVECOL);
- setBorderColor(pWindow->m_sSpecialRenderData.inactiveBorderColor.toUnderlying() >= 0 ?
- CGradientValueData(CColor(pWindow->m_sSpecialRenderData.inactiveBorderColor.toUnderlying())) :
- *INACTIVECOLOR);
+ setBorderColor(pWindow->m_sSpecialRenderData.inactiveBorderColor.toUnderlying().m_vColors.empty() ? *INACTIVECOLOR :
+ pWindow->m_sSpecialRenderData.inactiveBorderColor.toUnderlying());
}
}
diff --git a/src/Window.cpp b/src/Window.cpp
index 818b4089..5a50713b 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -614,14 +614,42 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
m_sAdditionalConfigData.animationStyle = STYLE;
} else if (r.szRule.starts_with("bordercolor")) {
try {
- std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
-
- if (colorPart.contains(' ')) {
- // we have a space, 2 values
- m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' ')));
- m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1));
- } else {
- m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart);
+ // Each vector will only get used if it has at least one color
+ CGradientValueData activeBorderGradient = {};
+ CGradientValueData inactiveBorderGradient = {};
+ bool active = true;
+ CVarList colorsAndAngles = CVarList(removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)), 0, 's', true);
+
+ // Basic form has only two colors, everything else can be parsed as a gradient
+ if (colorsAndAngles.size() == 2 && !colorsAndAngles[1].contains("deg")) {
+ m_sSpecialRenderData.activeBorderColor = CGradientValueData(CColor(configStringToInt(colorsAndAngles[0])));
+ m_sSpecialRenderData.inactiveBorderColor = CGradientValueData(CColor(configStringToInt(colorsAndAngles[1])));
+ return;
+ }
+
+ for (auto& token : colorsAndAngles) {
+ // The first angle, or an explicit "0deg", splits the two gradients
+ if (active && token.contains("deg")) {
+ activeBorderGradient.m_fAngle = std::stoi(token.substr(0, token.size() - 3)) * (PI / 180.0);
+ active = false;
+ } else if (token.contains("deg"))
+ inactiveBorderGradient.m_fAngle = std::stoi(token.substr(0, token.size() - 3)) * (PI / 180.0);
+ else if (active)
+ activeBorderGradient.m_vColors.push_back(configStringToInt(token));
+ else
+ inactiveBorderGradient.m_vColors.push_back(configStringToInt(token));
+ }
+
+ // Includes sanity checks for the number of colors in each gradient
+ if (activeBorderGradient.m_vColors.size() > 10 || inactiveBorderGradient.m_vColors.size() > 10)
+ Debug::log(WARN, "Bordercolor rule \"{}\" has more than 10 colors in one gradient, ignoring", r.szRule);
+ else if (activeBorderGradient.m_vColors.empty())
+ Debug::log(WARN, "Bordercolor rule \"{}\" has no colors, ignoring", r.szRule);
+ else if (inactiveBorderGradient.m_vColors.empty())
+ m_sSpecialRenderData.activeBorderColor = activeBorderGradient;
+ else {
+ m_sSpecialRenderData.activeBorderColor = activeBorderGradient;
+ m_sSpecialRenderData.inactiveBorderColor = inactiveBorderGradient;
}
} catch (std::exception& e) { Debug::log(ERR, "BorderColor rule \"{}\" failed with: {}", r.szRule, e.what()); }
} else if (r.szRule == "dimaround") {
@@ -651,8 +679,8 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
}
void CWindow::updateDynamicRules() {
- m_sSpecialRenderData.activeBorderColor = -1;
- m_sSpecialRenderData.inactiveBorderColor = -1;
+ m_sSpecialRenderData.activeBorderColor = CGradientValueData();
+ m_sSpecialRenderData.inactiveBorderColor = CGradientValueData();
m_sSpecialRenderData.alpha = 1.f;
m_sSpecialRenderData.alphaInactive = -1.f;
m_sAdditionalConfigData.forceNoBlur = false;
diff --git a/src/Window.hpp b/src/Window.hpp
index d700af7e..bbe7dc07 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -106,13 +106,13 @@ class CWindowOverridableVar {
};
struct SWindowSpecialRenderData {
- CWindowOverridableVar<bool> alphaOverride = false;
- CWindowOverridableVar<float> alpha = 1.f;
- CWindowOverridableVar<bool> alphaInactiveOverride = false;
- CWindowOverridableVar<float> alphaInactive = -1.f; // -1 means unset
+ CWindowOverridableVar<bool> alphaOverride = false;
+ CWindowOverridableVar<float> alpha = 1.f;
+ CWindowOverridableVar<bool> alphaInactiveOverride = false;
+ CWindowOverridableVar<float> alphaInactive = -1.f; // -1 means unset
- CWindowOverridableVar<int64_t> activeBorderColor = -1; // -1 means unset
- CWindowOverridableVar<int64_t> inactiveBorderColor = -1; // -1 means unset
+ CWindowOverridableVar<CGradientValueData> activeBorderColor = CGradientValueData(); // empty color vector means unset
+ CWindowOverridableVar<CGradientValueData> inactiveBorderColor = CGradientValueData(); // empty color vector means unset
// set by the layout
CWindowOverridableVar<int> borderSize = -1; // -1 means unset
diff --git a/src/config/ConfigDataValues.hpp b/src/config/ConfigDataValues.hpp
index f6bf9881..14b5e51d 100644
--- a/src/config/ConfigDataValues.hpp
+++ b/src/config/ConfigDataValues.hpp
@@ -16,6 +16,7 @@ class ICustomConfigValueData {
class CGradientValueData : public ICustomConfigValueData {
public:
+ CGradientValueData(){};
CGradientValueData(CColor col) {
m_vColors.push_back(col);
};
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 490f14c9..79855d27 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -1138,9 +1138,9 @@ std::string dispatchSetProp(std::string request) {
} else if (PROP == "alphainactive") {
PWINDOW->m_sSpecialRenderData.alphaInactive.forceSetIgnoreLocked(std::stof(VAL), lock);
} else if (PROP == "activebordercolor") {
- PWINDOW->m_sSpecialRenderData.activeBorderColor.forceSetIgnoreLocked(configStringToInt(VAL), lock);
+ PWINDOW->m_sSpecialRenderData.activeBorderColor.forceSetIgnoreLocked(CGradientValueData(CColor(configStringToInt(VAL))), lock);
} else if (PROP == "inactivebordercolor") {
- PWINDOW->m_sSpecialRenderData.inactiveBorderColor.forceSetIgnoreLocked(configStringToInt(VAL), lock);
+ PWINDOW->m_sSpecialRenderData.inactiveBorderColor.forceSetIgnoreLocked(CGradientValueData(CColor(configStringToInt(VAL))), lock);
} else if (PROP == "forcergbx") {
PWINDOW->m_sAdditionalConfigData.forceRGBX.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "bordersize") {