From deb077c34653eab251bfe71970bb5987913e7c6d Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 29 Dec 2024 19:21:20 +0100 Subject: [PATCH] ctm: add an internal fade animation to ctm transitions --- src/config/ConfigManager.cpp | 4 +++ src/managers/AnimationManager.cpp | 6 ++++ src/protocols/CTMControl.cpp | 50 +++++++++++++++++++++++++++++-- src/protocols/CTMControl.hpp | 10 +++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a9796bdd..65f9cb13 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -774,6 +774,8 @@ void CConfigManager::reload() { void CConfigManager::setDefaultAnimationVars() { if (isFirstLaunch) { + INITANIMCFG("__internal_fadeCTM"); + INITANIMCFG("global"); INITANIMCFG("windows"); INITANIMCFG("layers"); @@ -811,6 +813,8 @@ void CConfigManager::setDefaultAnimationVars() { // init the values animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr}; + animationConfig["__internal_fadeCTM"] = {false, "linear", "", 5.F, 1, &animationConfig["__internal_fadeCTM"], nullptr}; + CREATEANIMCFG("windows", "global"); CREATEANIMCFG("layers", "global"); CREATEANIMCFG("fade", "global"); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index e3309282..cff438b1 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -30,6 +30,9 @@ CAnimationManager::CAnimationManager() { std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; m_mBezierCurves["default"].setup(&points); + points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)}; + m_mBezierCurves["linear"].setup(&points); + m_pAnimationTimer = SP(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr)); g_pEventLoopManager->addTimer(m_pAnimationTimer); } @@ -40,6 +43,9 @@ void CAnimationManager::removeAllBeziers() { // add the default one std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; m_mBezierCurves["default"].setup(&points); + + points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)}; + m_mBezierCurves["linear"].setup(&points); } void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) { diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index cddad830..42c84e8f 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -81,6 +81,52 @@ void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* r std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; }); } -void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { - monitor->setCTM(ctm); +CHyprlandCTMControlProtocol::SCTMData::SCTMData() { + progress.create(g_pConfigManager->getAnimationPropertyConfig("__internal_fadeCTM"), AVARDAMAGE_NONE); + progress.setValueAndWarp(0.F); +} + +void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { + + std::erase_if(m_mCTMDatas, [](const auto& el) { return !el.first; }); + + if (!m_mCTMDatas.contains(monitor)) + m_mCTMDatas[monitor] = std::make_unique(); + + auto& data = m_mCTMDatas.at(monitor); + + data->ctmFrom = data->ctmTo; + data->ctmTo = ctm; + + data->progress.setValueAndWarp(0.F); + data->progress = 1.F; + + monitor->setCTM(data->ctmFrom); + + data->progress.setUpdateCallback([monitor = PHLMONITORREF{monitor}, this](void* self) { + if (!monitor || !m_mCTMDatas.contains(monitor)) + return; + auto& data = m_mCTMDatas.at(monitor); + const auto from = data->ctmFrom.getMatrix(); + const auto to = data->ctmTo.getMatrix(); + const auto PROGRESS = data->progress.getPercent(); + + static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; }; + + std::array mtx; + for (size_t i = 0; i < 9; ++i) { + mtx[i] = lerp(from[i], to[i], PROGRESS); + } + + monitor->setCTM(mtx); + }); + + data->progress.setCallbackOnEnd([monitor = PHLMONITORREF{monitor}, this](void* self) { + if (!monitor || !m_mCTMDatas.contains(monitor)) { + monitor->setCTM(Mat3x3::identity()); + return; + } + auto& data = m_mCTMDatas.at(monitor); + monitor->setCTM(data->ctmTo); + }); } diff --git a/src/protocols/CTMControl.hpp b/src/protocols/CTMControl.hpp index 70bc79bc..51820f20 100644 --- a/src/protocols/CTMControl.hpp +++ b/src/protocols/CTMControl.hpp @@ -6,6 +6,8 @@ #include "WaylandProtocol.hpp" #include "hyprland-ctm-control-v1.hpp" #include +#include +#include "../helpers/AnimatedVariable.hpp" class CMonitor; @@ -36,6 +38,14 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { // std::vector> m_vManagers; + // + struct SCTMData { + SCTMData(); + Mat3x3 ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity(); + CAnimatedVariable progress; + }; + std::map> m_mCTMDatas; + friend class CHyprlandCTMControlResource; };