From 549fdf63f6f72fadf4e1f67f42fc2a99d625b42e Mon Sep 17 00:00:00 2001 From: Jef <54236+ElJeffe@users.noreply.github.com> Date: Sun, 13 Nov 2022 20:33:13 +0100 Subject: [PATCH] Add bordercolor windowrule (#992) * Add bordercolor windowrule * remove spaces form bordercolor rule + typo Co-authored-by: Jef Steelant --- src/Compositor.cpp | 4 +++- src/Window.hpp | 3 +++ src/config/ConfigManager.cpp | 44 ++++------------------------------- src/events/Windows.cpp | 20 +++++++++++++--- src/helpers/MiscFunctions.cpp | 36 ++++++++++++++++++++++++++++ src/helpers/MiscFunctions.hpp | 1 + 6 files changed, 65 insertions(+), 43 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 4638f3f0..b1bbe800 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1415,7 +1415,9 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) { if (RENDERDATA.isBorderColor) pWindow->m_cRealBorderColor = RENDERDATA.borderColor; else - pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL); + pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? + (pWindow->m_sSpecialRenderData.activeBorderColor >= 0 ? pWindow->m_sSpecialRenderData.activeBorderColor : *ACTIVECOL) : + (pWindow->m_sSpecialRenderData.inactiveBorderColor >= 0 ? pWindow->m_sSpecialRenderData.inactiveBorderColor : *INACTIVECOL)); // opacity diff --git a/src/Window.hpp b/src/Window.hpp index 0e3ce9a5..a8e1bd6b 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -18,6 +18,9 @@ struct SWindowSpecialRenderData { float alpha = 1.f; float alphaInactive = -1.f; // -1 means unset + int64_t activeBorderColor = -1; // -1 means unset + int64_t inactiveBorderColor = -1; // -1 means unset + // set by the layout bool rounding = true; bool border = true; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index b38dfea5..63227479 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -312,45 +312,10 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s if (CONFIGENTRY->intValue != -INT64_MAX) { try { - if (VALUE.find("0x") == 0) { - // Values with 0x are hex - const auto VALUEWITHOUTHEX = VALUE.substr(2); - CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16); - } else if (VALUE.find("rgba(") == 0 && VALUE.find(")") == VALUE.length() - 1) { - const auto VALUEWITHOUTFUNC = VALUE.substr(5, VALUE.length() - 6); - - if (removeBeginEndSpacesTabs(VALUEWITHOUTFUNC).length() != 8) { - Debug::log(WARN, "invalid length %i for rgba", VALUEWITHOUTFUNC.length()); - parseError = "rgba() expects length of 8 characters (4 bytes)"; - return; - } - - const auto RGBA = std::stol(VALUEWITHOUTFUNC, nullptr, 16); - - // now we need to RGBA -> ARGB. The config holds ARGB only. - CONFIGENTRY->intValue = (RGBA >> 8) + 0x1000000 * (RGBA & 0xFF); - } else if (VALUE.find("rgb(") == 0 && VALUE.find(")") == VALUE.length() - 1) { - const auto VALUEWITHOUTFUNC = VALUE.substr(4, VALUE.length() - 5); - - if (removeBeginEndSpacesTabs(VALUEWITHOUTFUNC).length() != 6) { - Debug::log(WARN, "invalid length %i for rgb", VALUEWITHOUTFUNC.length()); - parseError = "rgb() expects length of 6 characters (3 bytes)"; - return; - } - - const auto RGB = std::stol(VALUEWITHOUTFUNC, nullptr, 16); - - CONFIGENTRY->intValue = RGB + 0xFF000000; // 0xFF for opaque - } else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) { - CONFIGENTRY->intValue = 1; - } else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) { - CONFIGENTRY->intValue = 0; - } - else - CONFIGENTRY->intValue = stol(VALUE); - } catch (...) { + CONFIGENTRY->intValue = configStringToInt(VALUE); + } catch (std::exception& e) { Debug::log(WARN, "Error reading value of %s", COMMAND.c_str()); - parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">."; + parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">. " + e.what(); } } else if (CONFIGENTRY->floatValue != -__FLT_MAX__) { try { @@ -717,7 +682,8 @@ bool windowRuleValid(const std::string& RULE) { && RULE != "windowdance" && RULE.find("animation") != 0 && RULE.find("rounding") != 0 - && RULE.find("workspace") != 0); + && RULE.find("workspace") != 0 + && RULE.find("bordercolor") != 0); } void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) { diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 000d1e33..3dcd7dc0 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -187,10 +187,10 @@ void Events::listener_mapWindow(void* owner, void* data) { } } else if (r.szRule.find("opacity") == 0) { try { - std::string alphaPart = r.szRule.substr(r.szRule.find_first_of(' ') + 1); + std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); if (alphaPart.contains(' ')) { - // we have a comma, 2 values + // we have a space, 2 values PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' '))); PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1)); } else { @@ -216,6 +216,20 @@ void Events::listener_mapWindow(void* owner, void* data) { } else { Debug::log(ERR, "Rule idleinhibit: unknown mode %s", IDLERULE.c_str()); } + } else if (r.szRule.find("bordercolor") == 0) { + try { + std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); + + if (colorPart.contains(' ')) { + // we have a space, 2 values + PWINDOW->m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' '))); + PWINDOW->m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1)); + } else { + PWINDOW->m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart); + } + } catch(std::exception& e) { + Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); + } } } @@ -259,7 +273,7 @@ void Events::listener_mapWindow(void* owner, void* data) { if (!PWORKSPACE) { std::string workspaceName = ""; int workspaceID = 0; - + if (requestedWorkspace.find("name:") == 0) { workspaceName = requestedWorkspace.substr(5); workspaceID = g_pCompositor->getNextAvailableNamedWorkspace(); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index bf20f390..706bb31e 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -450,3 +450,39 @@ int64_t getPPIDof(int64_t pid) { } #endif } + +int64_t configStringToInt(const std::string& VALUE) { + if (VALUE.find("0x") == 0) { + // Values with 0x are hex + const auto VALUEWITHOUTHEX = VALUE.substr(2); + return stol(VALUEWITHOUTHEX, nullptr, 16); + } else if (VALUE.find("rgba(") == 0 && VALUE.find(")") == VALUE.length() - 1) { + const auto VALUEWITHOUTFUNC = VALUE.substr(5, VALUE.length() - 6); + + if (removeBeginEndSpacesTabs(VALUEWITHOUTFUNC).length() != 8) { + Debug::log(WARN, "invalid length %i for rgba", VALUEWITHOUTFUNC.length()); + throw std::invalid_argument("rgba() expects length of 8 characters (4 bytes)"); + } + + const auto RGBA = std::stol(VALUEWITHOUTFUNC, nullptr, 16); + + // now we need to RGBA -> ARGB. The config holds ARGB only. + return (RGBA >> 8) + 0x1000000 * (RGBA & 0xFF); + } else if (VALUE.find("rgb(") == 0 && VALUE.find(")") == VALUE.length() - 1) { + const auto VALUEWITHOUTFUNC = VALUE.substr(4, VALUE.length() - 5); + + if (removeBeginEndSpacesTabs(VALUEWITHOUTFUNC).length() != 6) { + Debug::log(WARN, "invalid length %i for rgb", VALUEWITHOUTFUNC.length()); + throw std::invalid_argument("rgb() expects length of 6 characters (3 bytes)"); + } + + const auto RGB = std::stol(VALUEWITHOUTFUNC, nullptr, 16); + + return RGB + 0xFF000000; // 0xFF for opaque + } else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) { + return 1; + } else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) { + return 0; + } + return stol(VALUE); +} \ No newline at end of file diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index 55d51f07..9f30960e 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -15,6 +15,7 @@ float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Ve void logSystemInfo(); std::string execAndGet(const char*); int64_t getPPIDof(int64_t pid); +int64_t configStringToInt(const std::string&); float getPlusMinusKeywordResult(std::string in, float relative);