summaryrefslogtreecommitdiff
path: root/src/protocols
diff options
context:
space:
mode:
authorvaxerski <vaxry@vaxry.net>2024-12-29 19:21:20 +0100
committervaxerski <vaxry@vaxry.net>2024-12-29 19:21:20 +0100
commitdeb077c34653eab251bfe71970bb5987913e7c6d (patch)
tree2258d060dff1a1fa252bf6a1e92ca5c58049a5bf /src/protocols
parent3f40d6d9361d0c5fec558b7549e58203fbe5cbd7 (diff)
ctm: add an internal fade animation to ctm transitions
Diffstat (limited to 'src/protocols')
-rw-r--r--src/protocols/CTMControl.cpp48
-rw-r--r--src/protocols/CTMControl.hpp10
2 files changed, 57 insertions, 1 deletions
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; });
}
+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);
+ });
}
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 <unordered_map>
+#include <map>
+#include "../helpers/AnimatedVariable.hpp"
class CMonitor;
@@ -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;
};