summaryrefslogtreecommitdiff
path: root/src/managers/animation/AnimationManager.cpp
diff options
context:
space:
mode:
authorbea4dev <34712108+bea4dev@users.noreply.github.com>2025-11-24 00:48:15 +0900
committerGitHub <noreply@github.com>2025-11-23 15:48:15 +0000
commit2b0fd417d32278159d0ca1d23fb997588c37995b (patch)
tree522f5e65e52d211debfcbf79b4140e34a34b9979 /src/managers/animation/AnimationManager.cpp
parent56904edbd24fd5e36968d02132539b7b7eb25ea7 (diff)
animation: improve animations on multi refresh rate monitors (#12418)
Diffstat (limited to 'src/managers/animation/AnimationManager.cpp')
-rw-r--r--src/managers/animation/AnimationManager.cpp47
1 files changed, 26 insertions, 21 deletions
diff --git a/src/managers/animation/AnimationManager.cpp b/src/managers/animation/AnimationManager.cpp
index 38efb829..c304fc56 100644
--- a/src/managers/animation/AnimationManager.cpp
+++ b/src/managers/animation/AnimationManager.cpp
@@ -18,16 +18,7 @@
static int wlTick(SP<CEventLoopTimer> self, void* data) {
if (g_pAnimationManager)
- g_pAnimationManager->onTicked();
-
- if (g_pCompositor->m_sessionActive && g_pAnimationManager && g_pHookSystem && !g_pCompositor->m_unsafeState &&
- std::ranges::any_of(g_pCompositor->m_monitors, [](const auto& mon) { return mon->m_enabled && mon->m_output; })) {
- g_pAnimationManager->tick();
- EMIT_HOOK_EVENT("tick", nullptr);
- }
-
- if (g_pAnimationManager && g_pAnimationManager->shouldTickForNext())
- g_pAnimationManager->scheduleTick();
+ g_pAnimationManager->frameTick();
return 0;
}
@@ -249,26 +240,40 @@ void CHyprAnimationManager::tick() {
tickDone();
}
-void CHyprAnimationManager::scheduleTick() {
- if (m_tickScheduled)
+void CHyprAnimationManager::frameTick() {
+ onTicked();
+
+ if (!shouldTickForNext())
return;
- m_tickScheduled = true;
+ if (!g_pCompositor->m_sessionActive || !g_pHookSystem || g_pCompositor->m_unsafeState ||
+ !std::ranges::any_of(g_pCompositor->m_monitors, [](const auto& mon) { return mon->m_enabled && mon->m_output; }))
+ return;
- const auto PMOSTHZ = g_pHyprRenderer->m_mostHzMonitor;
+ if (!m_lastTickValid || m_lastTickTimer.getMillis() >= 1.0f) {
+ m_lastTickTimer.reset();
+ m_lastTickValid = true;
- if (!PMOSTHZ) {
- m_animationTimer->updateTimeout(std::chrono::milliseconds(16));
- return;
+ tick();
+ EMIT_HOOK_EVENT("tick", nullptr);
}
- float refreshDelayMs = std::floor(1000.f / PMOSTHZ->m_refreshRate);
+ if (shouldTickForNext())
+ scheduleTick();
+}
- const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(Time::steadyNow() - PMOSTHZ->m_lastPresentationTimer.chrono()).count() / 1000.F;
+void CHyprAnimationManager::scheduleTick() {
+ if (m_tickScheduled)
+ return;
- const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it
+ m_tickScheduled = true;
+
+ if (!m_animationTimer || !g_pEventLoopManager) {
+ m_tickScheduled = false;
+ return;
+ }
- m_animationTimer->updateTimeout(std::chrono::milliseconds(sc<int>(std::floor(TOPRES))));
+ m_animationTimer->updateTimeout(std::chrono::milliseconds(1));
}
void CHyprAnimationManager::onTicked() {