ctm: add an internal fade animation to ctm transitions

This commit is contained in:
Vaxry 2024-12-29 19:21:20 +01:00
parent 3f40d6d936
commit deb077c346
4 changed files with 68 additions and 2 deletions

View file

@ -774,6 +774,8 @@ void CConfigManager::reload() {
void CConfigManager::setDefaultAnimationVars() { void CConfigManager::setDefaultAnimationVars() {
if (isFirstLaunch) { if (isFirstLaunch) {
INITANIMCFG("__internal_fadeCTM");
INITANIMCFG("global"); INITANIMCFG("global");
INITANIMCFG("windows"); INITANIMCFG("windows");
INITANIMCFG("layers"); INITANIMCFG("layers");
@ -811,6 +813,8 @@ void CConfigManager::setDefaultAnimationVars() {
// init the values // init the values
animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr}; 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("windows", "global");
CREATEANIMCFG("layers", "global"); CREATEANIMCFG("layers", "global");
CREATEANIMCFG("fade", "global"); CREATEANIMCFG("fade", "global");

View file

@ -30,6 +30,9 @@ CAnimationManager::CAnimationManager() {
std::vector<Vector2D> points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; std::vector<Vector2D> points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)};
m_mBezierCurves["default"].setup(&points); m_mBezierCurves["default"].setup(&points);
points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)};
m_mBezierCurves["linear"].setup(&points);
m_pAnimationTimer = SP<CEventLoopTimer>(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr)); m_pAnimationTimer = SP<CEventLoopTimer>(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr));
g_pEventLoopManager->addTimer(m_pAnimationTimer); g_pEventLoopManager->addTimer(m_pAnimationTimer);
} }
@ -40,6 +43,9 @@ void CAnimationManager::removeAllBeziers() {
// add the default one // add the default one
std::vector<Vector2D> points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; std::vector<Vector2D> points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)};
m_mBezierCurves["default"].setup(&points); 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) { void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) {

View file

@ -81,6 +81,52 @@ void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* r
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; }); std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
} }
void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { CHyprlandCTMControlProtocol::SCTMData::SCTMData() {
monitor->setCTM(ctm); 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<SCTMData>();
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<float, 9> 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);
});
} }

View file

@ -6,6 +6,8 @@
#include "WaylandProtocol.hpp" #include "WaylandProtocol.hpp"
#include "hyprland-ctm-control-v1.hpp" #include "hyprland-ctm-control-v1.hpp"
#include <unordered_map> #include <unordered_map>
#include <map>
#include "../helpers/AnimatedVariable.hpp"
class CMonitor; class CMonitor;
@ -36,6 +38,14 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol {
// //
std::vector<SP<CHyprlandCTMControlResource>> m_vManagers; std::vector<SP<CHyprlandCTMControlResource>> m_vManagers;
//
struct SCTMData {
SCTMData();
Mat3x3 ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity();
CAnimatedVariable<float> progress;
};
std::map<PHLMONITORREF, std::unique_ptr<SCTMData>> m_mCTMDatas;
friend class CHyprlandCTMControlResource; friend class CHyprlandCTMControlResource;
}; };