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 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::frameTick() { + onTicked(); + + if (!shouldTickForNext()) + return; + + 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; + + if (!m_lastTickValid || m_lastTickTimer.getMillis() >= 1.0f) { + m_lastTickTimer.reset(); + m_lastTickValid = true; + + tick(); + EMIT_HOOK_EVENT("tick", nullptr); + } + + if (shouldTickForNext()) + scheduleTick(); +} + void CHyprAnimationManager::scheduleTick() { if (m_tickScheduled) return; m_tickScheduled = true; - const auto PMOSTHZ = g_pHyprRenderer->m_mostHzMonitor; - - if (!PMOSTHZ) { - m_animationTimer->updateTimeout(std::chrono::milliseconds(16)); + if (!m_animationTimer || !g_pEventLoopManager) { + m_tickScheduled = false; return; } - float refreshDelayMs = std::floor(1000.f / PMOSTHZ->m_refreshRate); - - const float SINCEPRES = std::chrono::duration_cast(Time::steadyNow() - PMOSTHZ->m_lastPresentationTimer.chrono()).count() / 1000.F; - - const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it - - m_animationTimer->updateTimeout(std::chrono::milliseconds(sc(std::floor(TOPRES)))); + m_animationTimer->updateTimeout(std::chrono::milliseconds(1)); } void CHyprAnimationManager::onTicked() { diff --git a/src/managers/animation/AnimationManager.hpp b/src/managers/animation/AnimationManager.hpp index 0631e7c7..2f411879 100644 --- a/src/managers/animation/AnimationManager.hpp +++ b/src/managers/animation/AnimationManager.hpp @@ -6,6 +6,7 @@ #include "../../defines.hpp" #include "../../helpers/AnimatedVariable.hpp" #include "../../desktop/DesktopTypes.hpp" +#include "../../helpers/time/Timer.hpp" #include "../eventLoop/EventLoopTimer.hpp" class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { @@ -13,6 +14,7 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { CHyprAnimationManager(); void tick(); + void frameTick(); virtual void scheduleTick(); virtual void onTicked(); @@ -52,7 +54,9 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { float m_lastTickTimeMs; private: - bool m_tickScheduled = false; + bool m_tickScheduled = false; + bool m_lastTickValid = false; + CTimer m_lastTickTimer; }; inline UP g_pAnimationManager; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 50fd339f..0e322284 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1247,6 +1247,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) { if (!g_pCompositor->m_sessionActive) return; + if (g_pAnimationManager) + g_pAnimationManager->frameTick(); + if (pMonitor->m_id == m_mostHzMonitor->m_id || *PVFR == 1) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that