diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 9826ad15..f42fa3a5 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -118,25 +118,28 @@ CScreencopyClient::~CScreencopyClient() { } CScreencopyClient::CScreencopyClient() { - lastMeasure = std::chrono::system_clock::now(); + lastMeasure.reset(); + lastFrame.reset(); tickCallback = g_pHookSystem->hookDynamic("tick", [&](void* self, std::any data) { onTick(); }); } void CScreencopyClient::onTick() { - const auto SINCELAST = std::chrono::duration_cast(std::chrono::system_clock::now() - lastMeasure).count() / 1000.0; - - if (SINCELAST < 0.5) + if (lastMeasure.getMillis() < 500) return; framesInLastHalfSecond = frameCounter; frameCounter = 0; - lastMeasure = std::chrono::system_clock::now(); + lastMeasure.reset(); + + const auto LASTFRAMEDELTA = lastFrame.getMillis() / 1000.0; + const bool FRAMEAWAITING = std::ranges::any_of(g_pProtocolManager->m_pScreencopyProtocolManager->m_lFrames, [&](const auto& frame) { return frame.client == this; }) || + std::ranges::any_of(g_pProtocolManager->m_pToplevelExportProtocolManager->m_lFrames, [&](const auto& frame) { return frame.client == this; }); if (framesInLastHalfSecond > 3 && !sentScreencast) { EMIT_HOOK_EVENT("screencast", (std::vector{1, (uint64_t)framesInLastHalfSecond, (uint64_t)clientOwner})); g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "1," + std::to_string(clientOwner)}); sentScreencast = true; - } else if (framesInLastHalfSecond < 4 && sentScreencast) { + } else if (framesInLastHalfSecond < 4 && sentScreencast && LASTFRAMEDELTA > 1.0 && !FRAMEAWAITING) { EMIT_HOOK_EVENT("screencast", (std::vector{0, (uint64_t)framesInLastHalfSecond, (uint64_t)clientOwner})); g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "0," + std::to_string(clientOwner)}); sentScreencast = false; @@ -350,6 +353,7 @@ void CScreencopyProtocolManager::shareAllFrames(CMonitor* pMonitor, bool dmabuf) shareFrame(f); + f->client->lastFrame.reset(); ++f->client->frameCounter; framesToRemove.push_back(f); diff --git a/src/protocols/Screencopy.hpp b/src/protocols/Screencopy.hpp index 17b5ed0b..f0634427 100644 --- a/src/protocols/Screencopy.hpp +++ b/src/protocols/Screencopy.hpp @@ -6,6 +6,7 @@ #include #include #include "../managers/HookSystemManager.hpp" +#include "../helpers/Timer.hpp" class CMonitor; @@ -20,20 +21,21 @@ class CScreencopyClient { CScreencopyClient(); ~CScreencopyClient(); - int ref = 0; - wl_resource* resource = nullptr; + int ref = 0; + wl_resource* resource = nullptr; - eClientOwners clientOwner = CLIENT_SCREENCOPY; + eClientOwners clientOwner = CLIENT_SCREENCOPY; - int frameCounter = 0; - int framesInLastHalfSecond = 0; - std::chrono::system_clock::time_point lastMeasure; - bool sentScreencast = false; + int frameCounter = 0; + int framesInLastHalfSecond = 0; + CTimer lastMeasure; + CTimer lastFrame; + bool sentScreencast = false; - void onTick(); - HOOK_CALLBACK_FN* tickCallback = nullptr; + void onTick(); + HOOK_CALLBACK_FN* tickCallback = nullptr; - bool operator==(const CScreencopyClient& other) const { + bool operator==(const CScreencopyClient& other) const { return resource == other.resource; } }; @@ -94,4 +96,6 @@ class CScreencopyProtocolManager { void sendFrameDamage(SScreencopyFrame* frame); bool copyFrameDmabuf(SScreencopyFrame* frame); bool copyFrameShm(SScreencopyFrame* frame, timespec* now); + + friend class CScreencopyClient; }; \ No newline at end of file diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index f78058f6..7a1d3d85 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -300,6 +300,7 @@ void CToplevelExportProtocolManager::onMonitorRender(CMonitor* pMonitor) { shareFrame(f); + f->client->lastFrame.reset(); ++f->client->frameCounter; framesToRemove.push_back(f); diff --git a/src/protocols/ToplevelExport.hpp b/src/protocols/ToplevelExport.hpp index eb94fb86..45e979f6 100644 --- a/src/protocols/ToplevelExport.hpp +++ b/src/protocols/ToplevelExport.hpp @@ -37,4 +37,6 @@ class CToplevelExportProtocolManager { bool copyFrameShm(SScreencopyFrame* frame, timespec* now); void onMonitorRender(CMonitor* pMonitor); + + friend class CScreencopyClient; }; \ No newline at end of file