From 940b602a70b90e57b999fb45bc4f2f18a16009fe Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Sun, 17 Mar 2024 21:29:47 +0300 Subject: [PATCH 01/10] input-field: new color features --- src/config/ConfigManager.cpp | 2 + src/renderer/widgets/PasswordInputField.cpp | 237 ++++++++++++-------- src/renderer/widgets/PasswordInputField.hpp | 16 +- 3 files changed, 156 insertions(+), 99 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a90b7b79..5c91db4a 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -100,6 +100,7 @@ void CConfigManager::init() { m_config.addSpecialConfigValue("input-field", "numlock_color", Hyprlang::INT{-1}); m_config.addSpecialConfigValue("input-field", "bothlock_color", Hyprlang::INT{-1}); m_config.addSpecialConfigValue("input-field", "invert_numlock", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("input-field", "swap_font", Hyprlang::INT{0}); SHADOWABLE("input-field"); m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true}); @@ -218,6 +219,7 @@ std::vector CConfigManager::getWidgetConfigs() { {"numlock_color", m_config.getSpecialConfigValue("input-field", "numlock_color", k.c_str())}, {"bothlock_color", m_config.getSpecialConfigValue("input-field", "bothlock_color", k.c_str())}, {"invert_numlock", m_config.getSpecialConfigValue("input-field", "invert_numlock", k.c_str())}, + {"swap_font", m_config.getSpecialConfigValue("input-field", "swap_font", k.c_str())}, SHADOWABLE("input-field"), } }); diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 107e7c36..cc9969a2 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -5,7 +5,6 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::unordered_map& props) : shadow(this, props, viewport_) { size = std::any_cast(props.at("size")); - inner = std::any_cast(props.at("inner_color")); outThick = std::any_cast(props.at("outline_thickness")); dots.size = std::any_cast(props.at("dots_size")); dots.spacing = std::any_cast(props.at("dots_spacing")); @@ -13,18 +12,20 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u dots.rounding = std::any_cast(props.at("dots_rounding")); fadeOnEmpty = std::any_cast(props.at("fade_on_empty")); fadeTimeoutMs = std::any_cast(props.at("fade_timeout")); - font = std::any_cast(props.at("font_color")); hiddenInputState.enabled = std::any_cast(props.at("hide_input")); rounding = std::any_cast(props.at("rounding")); configFailText = std::any_cast(props.at("fail_text")); - outerColor.transitionMs = std::any_cast(props.at("fail_transition")); - outerColor.main = std::any_cast(props.at("outer_color")); - outerColor.fail = std::any_cast(props.at("fail_color")); - outerColor.check = std::any_cast(props.at("check_color")); - outerColor.both = std::any_cast(props.at("bothlock_color")); - outerColor.caps = std::any_cast(props.at("capslock_color")); - outerColor.num = std::any_cast(props.at("numlock_color")); - outerColor.invertNum = std::any_cast(props.at("invert_numlock")); + col.transitionMs = std::any_cast(props.at("fail_transition")); + col.outer = std::any_cast(props.at("outer_color")); + col.inner = std::any_cast(props.at("inner_color")); + col.font = std::any_cast(props.at("font_color")); + col.fail = std::any_cast(props.at("fail_color")); + col.check = std::any_cast(props.at("check_color")); + col.both = std::any_cast(props.at("bothlock_color")); + col.caps = std::any_cast(props.at("capslock_color")); + col.num = std::any_cast(props.at("numlock_color")); + col.invertNum = std::any_cast(props.at("invert_numlock")); + col.swapFont = std::any_cast(props.at("swap_font")); viewport = viewport_; auto POS__ = std::any_cast(props.at("position")); @@ -35,16 +36,16 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u halign = std::any_cast(props.at("halign")); valign = std::any_cast(props.at("valign")); - pos = posFromHVAlign(viewport, size, pos, halign, valign); - dots.size = std::clamp(dots.size, 0.2f, 0.8f); - dots.spacing = std::clamp(dots.spacing, 0.f, 1.f); - outerColor.transitionMs = std::clamp(outerColor.transitionMs, 0, 1000); + pos = posFromHVAlign(viewport, size, pos, halign, valign); + dots.size = std::clamp(dots.size, 0.2f, 0.8f); + dots.spacing = std::clamp(dots.spacing, 0.f, 1.f); + col.transitionMs = std::clamp(col.transitionMs, 0, 1000); - outerColor.both = outerColor.both == -1 ? outerColor.main : outerColor.both; - outerColor.caps = outerColor.caps == -1 ? outerColor.main : outerColor.caps; - outerColor.num = outerColor.num == -1 ? outerColor.main : outerColor.num; + col.both = col.both == -1 ? col.outer : col.both; + col.caps = col.caps == -1 ? col.outer : col.caps; + col.num = col.num == -1 ? col.outer : col.num; - g_pHyprlock->m_bNumLock = outerColor.invertNum; + g_pHyprlock->m_bNumLock = col.invertNum; std::string placeholderText = std::any_cast(props.at("placeholder_text")); @@ -57,7 +58,7 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u request.asset = placeholderText; request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT; request.props["font_family"] = std::string{"Sans"}; - request.props["color"] = CColor{1.0 - font.r, 1.0 - font.g, 1.0 - font.b, 0.5}; + request.props["color"] = CColor{1.0 - col.font.r, 1.0 - col.font.g, 1.0 - col.font.b, 0.5}; request.props["font_size"] = (int)size.y / 4; g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); } @@ -177,7 +178,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { updateFade(); updateDots(); updateFailTex(); - updateOuter(); + updateColors(); updateHiddenInputState(); static auto TIMER = std::chrono::system_clock::now(); @@ -208,14 +209,12 @@ bool CPasswordInputField::draw(const SRenderData& data) { shadowData.opacity *= fade.a; shadow.draw(shadowData); - float passAlpha = checkWaiting ? 0.5 : 1.0; - - CColor outerCol = outerColor.main; + CColor outerCol = col.outer; outerCol.a *= fade.a * data.opacity; - CColor innerCol = inner; + CColor innerCol = col.inner; innerCol.a *= fade.a * data.opacity; - CColor fontCol = font; - fontCol.a *= fade.a * data.opacity * passAlpha; + CColor fontCol = col.font; + fontCol.a *= fade.a * data.opacity; if (outThick > 0) { g_pRenderer->renderRect(outerBox, outerCol, rounding == -1 ? outerBox.h / 2.0 : rounding); @@ -304,7 +303,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { forceReload = true; } - return dots.currentAmount != passwordLength || fade.animated || outerColor.animated || redrawShadow || data.opacity < 1.0 || forceReload; + return dots.currentAmount != passwordLength || fade.animated || col.animated || redrawShadow || data.opacity < 1.0 || forceReload; } void CPasswordInputField::updateFailTex() { @@ -337,7 +336,7 @@ void CPasswordInputField::updateFailTex() { request.asset = placeholder.failText; request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT; request.props["font_family"] = std::string{"Sans"}; - request.props["color"] = outerColor.fail; + request.props["color"] = col.fail; request.props["font_size"] = (int)size.y / 4; g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); @@ -371,91 +370,141 @@ void CPasswordInputField::updateHiddenInputState() { hiddenInputState.lastQuadrant = (hiddenInputState.lastQuadrant + rand() % 3 + 1) % 4; } -void CPasswordInputField::updateOuter() { - if (outThick == 0) - return; +static void changeColor(const CColor& source, const CColor& target, CColor& subject, const double& multi, bool& animated) { - static auto OUTER = outerColor.main, TARGET = OUTER, SOURCE = OUTER; - static auto TIMER = std::chrono::system_clock::now(); + const auto DELTA = target - source; - if (outerColor.animated) { - if (outerColor.stateNum != (outerColor.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock) || outerColor.stateCaps != g_pHyprlock->m_bCapsLock) - SOURCE = outerColor.main; - } else - SOURCE = outerColor.main; + if (subject.r != target.r) { + subject.r += DELTA.r * multi; + animated = true; - outerColor.animated = false; - outerColor.stateNum = outerColor.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock; - outerColor.stateCaps = g_pHyprlock->m_bCapsLock; + if ((source.r < target.r && subject.r > target.r) || (source.r > target.r && subject.r < target.r)) + subject.r = target.r; + } - if (placeholder.failID.empty()) { - if (g_pHyprlock->m_bFadeStarted) { - if (TARGET == outerColor.check) - SOURCE = outerColor.main; - outerColor.transitionMs = 100; - TARGET = OUTER; - } else if (checkWaiting) - TARGET = outerColor.check; - else if (outerColor.both != OUTER && outerColor.stateCaps && outerColor.stateNum) - TARGET = outerColor.both; - else if (outerColor.caps != OUTER && outerColor.stateCaps) - TARGET = outerColor.caps; - else if (outerColor.num != OUTER && outerColor.stateNum) - TARGET = outerColor.num; - else - TARGET = OUTER; - } else { - SOURCE = outerColor.check; - TARGET = outerColor.fail; + if (subject.g != target.g) { + subject.g += DELTA.g * multi; + animated = true; - if (fade.animated || fade.a < 1.0) { - TARGET = OUTER; - SOURCE = outerColor.fail; - } + if ((source.g < target.g && subject.g > target.g) || (source.g > target.g && subject.g < target.g)) + subject.g = target.g; } - if (outerColor.main == TARGET) - return; - - if (outerColor.main == SOURCE && !fade.animated) - TIMER = std::chrono::system_clock::now(); + if (subject.b != target.b) { + subject.b += DELTA.b * multi; + animated = true; - const auto MULTI = outerColor.transitionMs == 0 ? - 1.0 : - std::clamp(std::chrono::duration_cast(std::chrono::system_clock::now() - TIMER).count() / (double)outerColor.transitionMs, 0.02, 0.5); - const auto DELTA = TARGET - SOURCE; + if ((source.b < target.b && subject.b > target.b) || (source.b > target.b && subject.b < target.b)) + subject.b = target.b; + } - if (outerColor.main.r != TARGET.r) { - outerColor.main.r += DELTA.r * MULTI; - outerColor.animated = true; + if (subject.a != target.a) { + subject.a += DELTA.a * multi; + animated = true; - if ((SOURCE.r < TARGET.r && outerColor.main.r > TARGET.r) || (SOURCE.r > TARGET.r && outerColor.main.r < TARGET.r)) - outerColor.main.r = TARGET.r; + if ((source.a < target.a && subject.a > target.a) || (source.a > target.a && subject.a < target.a)) + subject.a = target.a; } +} + +void CPasswordInputField::updateColors() { + static auto OUTER = col.outer, TARGET = OUTER, SOURCE = OUTER; + static auto INNER = col.inner, ITARGET = INNER, ISOURCE = INNER; + static auto FONT = col.font, FTARGET = FONT, FSOURCE = FONT; - if (outerColor.main.g != TARGET.g) { - outerColor.main.g += DELTA.g * MULTI; - outerColor.animated = true; + const bool BORDERLESS = outThick == 0; - if ((SOURCE.g < TARGET.g && outerColor.main.g > TARGET.g) || (SOURCE.g > TARGET.g && outerColor.main.g < TARGET.g)) - outerColor.main.g = TARGET.g; + if (col.animated) { + // some cases when events happen too quick (within transitionMs) + // TODO: find more? + const bool LOCKCHANGED = col.stateNum != (col.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock) || col.stateCaps != g_pHyprlock->m_bCapsLock; + const bool ANIMONCHECK = checkWaiting && TARGET == (BORDERLESS ? INNER : OUTER); + + if (LOCKCHANGED || ANIMONCHECK) { + SOURCE = BORDERLESS ? col.inner : col.outer; + // to avoid an edge case when check_color set to the same as outer. + FSOURCE = ANIMONCHECK && OUTER == col.check ? FONT : col.font; + ISOURCE = ANIMONCHECK && OUTER == col.check ? INNER : col.inner; + } + } else { + SOURCE = BORDERLESS ? col.inner : col.outer; + FSOURCE = col.font; + ISOURCE = col.inner; } - if (outerColor.main.b != TARGET.b) { - outerColor.main.b += DELTA.b * MULTI; - outerColor.animated = true; + col.stateNum = col.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock; + col.stateCaps = g_pHyprlock->m_bCapsLock; + + if (placeholder.failID.empty()) { + if (g_pHyprlock->m_bFadeStarted) { + if (TARGET == col.check) + SOURCE = BORDERLESS ? col.inner : col.outer; + col.transitionMs = 100; + TARGET = BORDERLESS ? INNER : OUTER; + } else if (checkWaiting) { + FTARGET = col.swapFont ? INNER : FONT; + const float PASSALPHA = FTARGET.a * 0.5; + FTARGET.a = PASSALPHA; + + TARGET = col.check; + ITARGET = col.swapFont ? FONT : INNER; + } else if (col.both != OUTER && col.stateCaps && col.stateNum) { + TARGET = col.both; + FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; + } else if (col.caps != OUTER && col.stateCaps) { + TARGET = col.caps; + FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; + } else if (col.num != OUTER && col.stateNum) { + TARGET = col.num; + FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; + } else { + // if quickly pressed after failure + if (BORDERLESS && col.animated && TARGET == col.fail) + SOURCE = col.inner; + + TARGET = BORDERLESS ? INNER : OUTER; + FTARGET = FONT; + ITARGET = INNER; + } + } else { + FSOURCE = col.swapFont ? INNER : FONT; + const float PASSALPHA = FSOURCE.a * 0.5; + FSOURCE.a = PASSALPHA; + FTARGET = FONT; + + SOURCE = col.check; + TARGET = col.fail; + ISOURCE = FONT; + ITARGET = FONT; - if ((SOURCE.b < TARGET.b && outerColor.main.b > TARGET.b) || (SOURCE.b > TARGET.b && outerColor.main.b < TARGET.b)) - outerColor.main.b = TARGET.b; + if (fade.animated || fade.a < 1.0) { + TARGET = BORDERLESS ? INNER : OUTER; + SOURCE = col.fail; + } } - if (outerColor.main.a != TARGET.a) { - outerColor.main.a += DELTA.a * MULTI; - outerColor.animated = true; + col.animated = false; + + const bool SWAPDONE = !BORDERLESS && col.swapFont ? col.inner == ITARGET : true; - if ((SOURCE.a < TARGET.a && outerColor.main.a > TARGET.a) || (SOURCE.a > TARGET.a && outerColor.main.a < TARGET.a)) - outerColor.main.a = TARGET.a; + if ((BORDERLESS ? col.inner : col.outer) == TARGET && col.font == FTARGET && SWAPDONE) { + col.shouldStart = true; + return; } - TIMER = std::chrono::system_clock::now(); + if (col.shouldStart) { + col.lastFrame = std::chrono::system_clock::now(); + col.shouldStart = false; + } + + const auto MULTI = col.transitionMs == 0 ? + 1.0 : + std::clamp(std::chrono::duration_cast(std::chrono::system_clock::now() - col.lastFrame).count() / (double)col.transitionMs, 0.016, 0.5); + + changeColor(SOURCE, TARGET, (BORDERLESS ? col.inner : col.outer), MULTI, col.animated); + changeColor(FSOURCE, FTARGET, col.font, MULTI, col.animated); + if (col.swapFont && !BORDERLESS) + changeColor(ISOURCE, ITARGET, col.inner, MULTI, col.animated); + + col.lastFrame = std::chrono::system_clock::now(); } diff --git a/src/renderer/widgets/PasswordInputField.hpp b/src/renderer/widgets/PasswordInputField.hpp index 6de0b370..0c719f55 100644 --- a/src/renderer/widgets/PasswordInputField.hpp +++ b/src/renderer/widgets/PasswordInputField.hpp @@ -24,7 +24,7 @@ class CPasswordInputField : public IWidget { void updateFade(); void updateFailTex(); void updateHiddenInputState(); - void updateOuter(); + void updateColors(); bool firstRender = true; bool redrawShadow = false; @@ -42,8 +42,6 @@ class CPasswordInputField : public IWidget { int outThick, rounding; - CColor inner, font; - struct { float currentAmount = 0; float speedPerSecond = 5; // actually per... something. I am unsure xD @@ -81,18 +79,26 @@ class CPasswordInputField : public IWidget { } hiddenInputState; struct { - CColor main; + CColor outer; + CColor inner; + CColor font; CColor fail; CColor check; CColor caps; CColor num; CColor both; + int transitionMs = 0; bool invertNum = false; bool animated = false; bool stateNum = false; bool stateCaps = false; - } outerColor; + bool swapFont = false; + bool shouldStart; + + // + std::chrono::system_clock::time_point lastFrame; + } col; bool fadeOnEmpty; uint64_t fadeTimeoutMs; From a93bfb529a753d6a8f88a8a3f893d9f80e2628a5 Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Sun, 17 Mar 2024 21:41:35 +0300 Subject: [PATCH 02/10] add nix HM --- nix/hm-module.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nix/hm-module.nix b/nix/hm-module.nix index c1e3c1fd..d60e5402 100644 --- a/nix/hm-module.nix +++ b/nix/hm-module.nix @@ -407,6 +407,12 @@ in { type = bool; default = false; }; + + swap_font = mkOption { + description = "Whether to swap font color with inner color on some events"; + type = bool; + default = false; + }; } // shadow; }); @@ -557,6 +563,7 @@ in { numlock_color = ${input-field.numlock_color} bothlock_color = ${input-field.bothlock_color} invert_numlock = ${boolToString input-field.invert_numlock} + swap_font = ${boolToString input-field.swap_font} position = ${toString input-field.position.x}, ${toString input-field.position.y} halign = ${input-field.halign} From bc967c0a36f8139caa6a7136a0888c02e7b5689e Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Sun, 17 Mar 2024 23:16:15 +0300 Subject: [PATCH 03/10] add workaround for faillasset not being shown on empty imput --- src/renderer/widgets/PasswordInputField.cpp | 7 ++++++- src/renderer/widgets/PasswordInputField.hpp | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index cc9969a2..a7bad293 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -303,6 +303,11 @@ bool CPasswordInputField::draw(const SRenderData& data) { forceReload = true; } + if (passwordLength == 0 && g_pHyprlock->getPasswordFailedAttempts() > failedAttempts) + forceReload = true; + + failedAttempts = g_pHyprlock->getPasswordFailedAttempts(); + return dots.currentAmount != passwordLength || fade.animated || col.animated || redrawShadow || data.opacity < 1.0 || forceReload; } @@ -327,7 +332,7 @@ void CPasswordInputField::updateFailTex() { placeholder.failText = configFailText; replaceAllFail(placeholder.failText, "$FAIL", FAIL.value()); - replaceAllFail(placeholder.failText, "$ATTEMPTS", std::to_string(g_pHyprlock->getPasswordFailedAttempts())); + replaceAllFail(placeholder.failText, "$ATTEMPTS", std::to_string(failedAttempts)); // query CAsyncResourceGatherer::SPreloadRequest request; diff --git a/src/renderer/widgets/PasswordInputField.hpp b/src/renderer/widgets/PasswordInputField.hpp index 0c719f55..319d2474 100644 --- a/src/renderer/widgets/PasswordInputField.hpp +++ b/src/renderer/widgets/PasswordInputField.hpp @@ -31,6 +31,7 @@ class CPasswordInputField : public IWidget { bool checkWaiting = false; size_t passwordLength = 0; + size_t failedAttempts = 0; Vector2D size; Vector2D pos; From eae7ce57ff086cfbcc0d8d025ebf07e95cacebd8 Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Sun, 17 Mar 2024 23:22:56 +0300 Subject: [PATCH 04/10] comment --- src/renderer/widgets/PasswordInputField.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index a7bad293..e1660b60 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -303,6 +303,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { forceReload = true; } + // TODO: find out why failAsset not shown on empty input if (passwordLength == 0 && g_pHyprlock->getPasswordFailedAttempts() > failedAttempts) forceReload = true; From 664aa9257a8876c3bc1fb1dac73d400a29c703ee Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Mon, 18 Mar 2024 02:02:30 +0300 Subject: [PATCH 05/10] change cfg option name --- nix/hm-module.nix | 4 ++-- src/config/ConfigManager.cpp | 4 ++-- src/renderer/widgets/PasswordInputField.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nix/hm-module.nix b/nix/hm-module.nix index d60e5402..506cd957 100644 --- a/nix/hm-module.nix +++ b/nix/hm-module.nix @@ -408,7 +408,7 @@ in { default = false; }; - swap_font = mkOption { + swap_font_color = mkOption { description = "Whether to swap font color with inner color on some events"; type = bool; default = false; @@ -563,7 +563,7 @@ in { numlock_color = ${input-field.numlock_color} bothlock_color = ${input-field.bothlock_color} invert_numlock = ${boolToString input-field.invert_numlock} - swap_font = ${boolToString input-field.swap_font} + swap_font_color = ${boolToString input-field.swap_font_color} position = ${toString input-field.position.x}, ${toString input-field.position.y} halign = ${input-field.halign} diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 5c91db4a..8b406929 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -100,7 +100,7 @@ void CConfigManager::init() { m_config.addSpecialConfigValue("input-field", "numlock_color", Hyprlang::INT{-1}); m_config.addSpecialConfigValue("input-field", "bothlock_color", Hyprlang::INT{-1}); m_config.addSpecialConfigValue("input-field", "invert_numlock", Hyprlang::INT{0}); - m_config.addSpecialConfigValue("input-field", "swap_font", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("input-field", "swap_font_color", Hyprlang::INT{0}); SHADOWABLE("input-field"); m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true}); @@ -219,7 +219,7 @@ std::vector CConfigManager::getWidgetConfigs() { {"numlock_color", m_config.getSpecialConfigValue("input-field", "numlock_color", k.c_str())}, {"bothlock_color", m_config.getSpecialConfigValue("input-field", "bothlock_color", k.c_str())}, {"invert_numlock", m_config.getSpecialConfigValue("input-field", "invert_numlock", k.c_str())}, - {"swap_font", m_config.getSpecialConfigValue("input-field", "swap_font", k.c_str())}, + {"swap_font_color", m_config.getSpecialConfigValue("input-field", "swap_font_color", k.c_str())}, SHADOWABLE("input-field"), } }); diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index e1660b60..211a1e95 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -25,7 +25,7 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u col.caps = std::any_cast(props.at("capslock_color")); col.num = std::any_cast(props.at("numlock_color")); col.invertNum = std::any_cast(props.at("invert_numlock")); - col.swapFont = std::any_cast(props.at("swap_font")); + col.swapFont = std::any_cast(props.at("swap_font_color")); viewport = viewport_; auto POS__ = std::any_cast(props.at("position")); From 441b4afaed5b61c195f8843b016a18d53f9020b9 Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Mon, 18 Mar 2024 18:02:38 +0300 Subject: [PATCH 06/10] remove TODO --- src/renderer/widgets/PasswordInputField.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 211a1e95..a4a59a2b 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -172,6 +172,10 @@ bool CPasswordInputField::draw(const SRenderData& data) { bool forceReload = false; + if (passwordLength == 0 && g_pHyprlock->getPasswordFailedAttempts() > failedAttempts) + forceReload = true; + + failedAttempts = g_pHyprlock->getPasswordFailedAttempts(); passwordLength = g_pHyprlock->getPasswordBufferDisplayLen(); checkWaiting = g_pHyprlock->passwordCheckWaiting(); @@ -303,12 +307,6 @@ bool CPasswordInputField::draw(const SRenderData& data) { forceReload = true; } - // TODO: find out why failAsset not shown on empty input - if (passwordLength == 0 && g_pHyprlock->getPasswordFailedAttempts() > failedAttempts) - forceReload = true; - - failedAttempts = g_pHyprlock->getPasswordFailedAttempts(); - return dots.currentAmount != passwordLength || fade.animated || col.animated || redrawShadow || data.opacity < 1.0 || forceReload; } @@ -424,7 +422,7 @@ void CPasswordInputField::updateColors() { // some cases when events happen too quick (within transitionMs) // TODO: find more? const bool LOCKCHANGED = col.stateNum != (col.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock) || col.stateCaps != g_pHyprlock->m_bCapsLock; - const bool ANIMONCHECK = checkWaiting && TARGET == (BORDERLESS ? INNER : OUTER); + const bool ANIMONCHECK = checkWaiting && (TARGET == (BORDERLESS ? INNER : OUTER) || TARGET == col.fail); if (LOCKCHANGED || ANIMONCHECK) { SOURCE = BORDERLESS ? col.inner : col.outer; From fc64fd8a16d0e2067a396b97089afbad52a6f02a Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Mon, 18 Mar 2024 19:35:47 +0300 Subject: [PATCH 07/10] small fix --- src/renderer/widgets/PasswordInputField.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index a4a59a2b..6d635ca4 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -463,8 +463,8 @@ void CPasswordInputField::updateColors() { FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; } else { // if quickly pressed after failure - if (BORDERLESS && col.animated && TARGET == col.fail) - SOURCE = col.inner; + if (col.animated && TARGET == col.fail) + SOURCE = BORDERLESS ? col.inner : col.outer; TARGET = BORDERLESS ? INNER : OUTER; FTARGET = FONT; From 19b1408d5323d8b8fccce9d4f96d7088081cf3bc Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Mon, 18 Mar 2024 22:14:42 +0300 Subject: [PATCH 08/10] one more edge check --- src/renderer/widgets/PasswordInputField.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 6d635ca4..521ea8be 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -425,10 +425,11 @@ void CPasswordInputField::updateColors() { const bool ANIMONCHECK = checkWaiting && (TARGET == (BORDERLESS ? INNER : OUTER) || TARGET == col.fail); if (LOCKCHANGED || ANIMONCHECK) { - SOURCE = BORDERLESS ? col.inner : col.outer; - // to avoid an edge case when check_color set to the same as outer. - FSOURCE = ANIMONCHECK && OUTER == col.check ? FONT : col.font; - ISOURCE = ANIMONCHECK && OUTER == col.check ? INNER : col.inner; + const bool EQUALCOLORS = ANIMONCHECK && OUTER == col.check; + // to avoid throttle when check_color set to the same as outer. + SOURCE = BORDERLESS ? (EQUALCOLORS ? INNER : col.inner) : col.outer; + FSOURCE = EQUALCOLORS ? FONT : col.font; + ISOURCE = EQUALCOLORS ? INNER : col.inner; } } else { SOURCE = BORDERLESS ? col.inner : col.outer; @@ -452,13 +453,13 @@ void CPasswordInputField::updateColors() { TARGET = col.check; ITARGET = col.swapFont ? FONT : INNER; - } else if (col.both != OUTER && col.stateCaps && col.stateNum) { + } else if (col.stateCaps && col.stateNum && col.both != OUTER) { TARGET = col.both; FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; - } else if (col.caps != OUTER && col.stateCaps) { + } else if (col.stateCaps && col.caps != OUTER) { TARGET = col.caps; FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; - } else if (col.num != OUTER && col.stateNum) { + } else if (col.stateNum && col.num != OUTER) { TARGET = col.num; FTARGET = col.swapFont && BORDERLESS ? INNER : FONT; } else { From abd70c91313db6c1a809f3e74c482eddbc400546 Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Tue, 19 Mar 2024 01:50:53 +0300 Subject: [PATCH 09/10] dedup changeColor function --- src/renderer/widgets/PasswordInputField.cpp | 40 +++++++-------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 521ea8be..cb1f9375 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -374,41 +374,25 @@ void CPasswordInputField::updateHiddenInputState() { hiddenInputState.lastQuadrant = (hiddenInputState.lastQuadrant + rand() % 3 + 1) % 4; } -static void changeColor(const CColor& source, const CColor& target, CColor& subject, const double& multi, bool& animated) { - - const auto DELTA = target - source; - - if (subject.r != target.r) { - subject.r += DELTA.r * multi; - animated = true; - - if ((source.r < target.r && subject.r > target.r) || (source.r > target.r && subject.r < target.r)) - subject.r = target.r; - } +static void changeChannel(const float& source, const float& target, float& subject, const double& multi, bool& animated, const float& delta) { - if (subject.g != target.g) { - subject.g += DELTA.g * multi; + if (subject != target) { + subject += delta * multi; animated = true; - if ((source.g < target.g && subject.g > target.g) || (source.g > target.g && subject.g < target.g)) - subject.g = target.g; + if ((source < target && subject > target) || (source > target && subject < target)) + subject = target; } +} - if (subject.b != target.b) { - subject.b += DELTA.b * multi; - animated = true; - - if ((source.b < target.b && subject.b > target.b) || (source.b > target.b && subject.b < target.b)) - subject.b = target.b; - } +static void changeColor(const CColor& source, const CColor& target, CColor& subject, const double& multi, bool& animated) { - if (subject.a != target.a) { - subject.a += DELTA.a * multi; - animated = true; + const auto DELTA = target - source; - if ((source.a < target.a && subject.a > target.a) || (source.a > target.a && subject.a < target.a)) - subject.a = target.a; - } + changeChannel(source.r, target.r, subject.r, multi, animated, DELTA.r); + changeChannel(source.g, target.g, subject.g, multi, animated, DELTA.g); + changeChannel(source.b, target.b, subject.b, multi, animated, DELTA.b); + changeChannel(source.a, target.a, subject.a, multi, animated, DELTA.a); } void CPasswordInputField::updateColors() { From 46b32750ed4ef75f7e1ef2879ffdb6fc3d0c1c98 Mon Sep 17 00:00:00 2001 From: bvr-yr Date: Tue, 19 Mar 2024 02:05:53 +0300 Subject: [PATCH 10/10] simplify more --- src/renderer/widgets/PasswordInputField.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index cb1f9375..3fb67b03 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -374,10 +374,12 @@ void CPasswordInputField::updateHiddenInputState() { hiddenInputState.lastQuadrant = (hiddenInputState.lastQuadrant + rand() % 3 + 1) % 4; } -static void changeChannel(const float& source, const float& target, float& subject, const double& multi, bool& animated, const float& delta) { +static void changeChannel(const float& source, const float& target, float& subject, const double& multi, bool& animated) { + + const float DELTA = target - source; if (subject != target) { - subject += delta * multi; + subject += DELTA * multi; animated = true; if ((source < target && subject > target) || (source > target && subject < target)) @@ -387,12 +389,10 @@ static void changeChannel(const float& source, const float& target, float& subje static void changeColor(const CColor& source, const CColor& target, CColor& subject, const double& multi, bool& animated) { - const auto DELTA = target - source; - - changeChannel(source.r, target.r, subject.r, multi, animated, DELTA.r); - changeChannel(source.g, target.g, subject.g, multi, animated, DELTA.g); - changeChannel(source.b, target.b, subject.b, multi, animated, DELTA.b); - changeChannel(source.a, target.a, subject.a, multi, animated, DELTA.a); + changeChannel(source.r, target.r, subject.r, multi, animated); + changeChannel(source.g, target.g, subject.g, multi, animated); + changeChannel(source.b, target.b, subject.b, multi, animated); + changeChannel(source.a, target.a, subject.a, multi, animated); } void CPasswordInputField::updateColors() {