From 2b0fd417d32278159d0ca1d23fb997588c37995b Mon Sep 17 00:00:00 2001 From: bea4dev <34712108+bea4dev@users.noreply.github.com> Date: Mon, 24 Nov 2025 00:48:15 +0900 Subject: animation: improve animations on multi refresh rate monitors (#12418) --- src/managers/animation/AnimationManager.cpp | 47 ++++++++++++++++------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'src/managers/animation/AnimationManager.cpp') 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::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(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(std::floor(TOPRES)))); + m_animationTimer->updateTimeout(std::chrono::milliseconds(1)); } void CHyprAnimationManager::onTicked() { -- cgit v1.2.3