fix: switch to own ticking system

This commit is contained in:
Matias 2025-07-17 12:30:28 +02:00
parent aae62208d6
commit 1351590ece
No known key found for this signature in database
GPG Key ID: ED35A6AC65A06B69

View File

@ -6,6 +6,7 @@
#include <any>
#include <hyprland/src/Compositor.hpp>
#include <hyprland/src/helpers/time/Time.hpp>
#include <hyprland/src/managers/eventLoop/EventLoopManager.hpp>
#include <hyprland/src/managers/input/InputManager.hpp>
#include <hyprland/src/plugins/HookSystem.hpp>
#include <hyprland/src/render/Renderer.hpp>
@ -33,13 +34,49 @@ void unregisterWindow(PHLWINDOW pWindow) {
g_wobblyWindows.erase(winref);
}
void tick() {
SP<CEventLoopTimer> g_wobbleTickTimer;
bool g_tickScheduled = false;
void scheduleTick() {
if (g_tickScheduled)
return;
g_tickScheduled = true;
const auto PMOSTHZ = g_pHyprRenderer->m_mostHzMonitor;
if (!PMOSTHZ) {
g_wobbleTickTimer->updateTimeout(std::chrono::milliseconds(16));
return;
}
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->m_refreshRate);
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(
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
g_wobbleTickTimer->updateTimeout(std::chrono::milliseconds((int)std::floor(TOPRES)));
}
void tick(SP<CEventLoopTimer> self, void* data) {
g_tickScheduled = false;
const auto now = Time::steadyNow();
std::erase_if(g_wobblyWindows, [&now](auto&& element) {
auto&& [window, wobble] = element;
const bool shouldErase = window->m_fadingOut or wobble.step(now);
if (not shouldErase) {
const CBox windowBox = window->getFullWindowBoundingBox();
const CBox wobbleBox = wobble.getBox();
@ -49,9 +86,13 @@ void tick() {
windowBox.width * wobbleBox.width,
windowBox.height * wobbleBox.height
));
}
return shouldErase;
});
if (not g_wobblyWindows.empty())
scheduleTick();
}
static SP<HOOK_CALLBACK_FN> g_openWindow = nullptr;
@ -121,6 +162,9 @@ void hkRenderWindow(
const auto windowBox = pWindow->getFullWindowBoundingBox();
if (shouldWobble) {
if (not g_tickScheduled)
scheduleTick();
PHLWINDOWREF ref {pWindow};
// create it if not exists
@ -195,11 +239,9 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
}
);
g_tick = HyprlandAPI::registerCallbackDynamic(
PHANDLE,
"tick",
[](void* self, SCallbackInfo& info, std::any data) { tick(); }
);
g_wobbleTickTimer =
SP<CEventLoopTimer>(new CEventLoopTimer(std::chrono::microseconds(500), tick, nullptr));
g_pEventLoopManager->addTimer(g_wobbleTickTimer);
{
static const auto METHODS = HyprlandAPI::findFunctionsByName(PHANDLE, "renderWindow");
@ -218,5 +260,6 @@ APICALL EXPORT void PLUGIN_EXIT() {
g_pRenderWindowHook = nullptr;
g_closeWindow = nullptr;
g_openWindow = nullptr;
g_tick = nullptr;
g_pEventLoopManager->removeTimer(g_wobbleTickTimer);
}