Skip to content

Commit

Permalink
ctm: add an internal fade animation to ctm transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Dec 29, 2024
1 parent 3f40d6d commit deb077c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,8 @@ void CConfigManager::reload() {

void CConfigManager::setDefaultAnimationVars() {
if (isFirstLaunch) {
INITANIMCFG("__internal_fadeCTM");

INITANIMCFG("global");
INITANIMCFG("windows");
INITANIMCFG("layers");
Expand Down Expand Up @@ -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");
Expand Down
6 changes: 6 additions & 0 deletions src/managers/AnimationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ CAnimationManager::CAnimationManager() {
std::vector<Vector2D> 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<CEventLoopTimer>(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr));
g_pEventLoopManager->addTimer(m_pAnimationTimer);
}
Expand All @@ -40,6 +43,9 @@ void CAnimationManager::removeAllBeziers() {
// add the default one
std::vector<Vector2D> 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) {
Expand Down
48 changes: 47 additions & 1 deletion src/protocols/CTMControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,52 @@ void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* r
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
}

CHyprlandCTMControlProtocol::SCTMData::SCTMData() {
progress.create(g_pConfigManager->getAnimationPropertyConfig("__internal_fadeCTM"), AVARDAMAGE_NONE);
progress.setValueAndWarp(0.F);
}

void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) {
monitor->setCTM(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);
});
}
10 changes: 10 additions & 0 deletions src/protocols/CTMControl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "WaylandProtocol.hpp"
#include "hyprland-ctm-control-v1.hpp"
#include <unordered_map>
#include <map>
#include "../helpers/AnimatedVariable.hpp"

class CMonitor;

Expand Down Expand Up @@ -36,6 +38,14 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol {
//
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;
};

Expand Down

2 comments on commit deb077c

@fxzzi
Copy link
Contributor

@fxzzi fxzzi commented on deb077c Dec 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks nice but does not work on multimonitor nvidia setups (nvidia issue 99% chance), provided more info here: https://discord.com/channels/961691461554950145/1292998806417309798/1323024585846685787

maybe disable this if user has nvidia gpu or if user has nvidia gpu plus at least more than one monitor is enabled.

i has reported it here: https://forums.developer.nvidia.com/t/560-release-feedback-discussion/300830/580?u=faz

@vaxerski
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you open an issue? Easier to track.

Please sign in to comment.