diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index a4d62506..7c25ed3f 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -1,5 +1,6 @@ #include "Screencopy.hpp" #include "../Compositor.hpp" +#include "../managers/eventLoop/EventLoopManager.hpp" #include "../managers/PointerManager.hpp" #include @@ -35,6 +36,20 @@ CScreencopyProtocolManager::CScreencopyProtocolManager() { wl_display_add_destroy_listener(g_pCompositor->m_sWLDisplay, &m_liDisplayDestroy); Debug::log(LOG, "ScreencopyProtocolManager started successfully!"); + + m_pSoftwareCursorTimer = makeShared( + std::nullopt, + [this](SP self, void* data) { + // TODO: make it per-monitor + for (auto& m : g_pCompositor->m_vMonitors) { + g_pPointerManager->unlockSoftwareForMonitor(m); + } + m_bTimerArmed = false; + + Debug::log(LOG, "[screencopy] Releasing software cursor lock"); + }, + nullptr); + g_pEventLoopManager->addTimer(m_pSoftwareCursorTimer); } static void handleCaptureOutput(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, wl_resource* output) { @@ -184,11 +199,6 @@ void CScreencopyProtocolManager::removeFrame(SScreencopyFrame* frame, bool force if (!frame) return; - if (frame->lockedSWCursors) { - g_pPointerManager->unlockSoftwareForMonitor(frame->pMonitor->self.lock()); - g_pPointerManager->damageCursor(frame->pMonitor->self.lock()); - } - std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return other == frame; }); wl_resource_set_user_data(frame->resource, nullptr); @@ -360,8 +370,15 @@ void CScreencopyProtocolManager::copyFrame(wl_client* client, wl_resource* resou g_pHyprRenderer->m_bDirectScanoutBlocked = true; if (PFRAME->overlayCursor && !PFRAME->lockedSWCursors) { PFRAME->lockedSWCursors = true; - g_pPointerManager->lockSoftwareForMonitor(PFRAME->pMonitor->self.lock()); - g_pPointerManager->damageCursor(PFRAME->pMonitor->self.lock()); + // TODO: make it per-monitor + if (!m_bTimerArmed) { + for (auto& m : g_pCompositor->m_vMonitors) { + g_pPointerManager->lockSoftwareForMonitor(m); + } + m_bTimerArmed = true; + Debug::log(LOG, "[screencopy] Locking sw cursors due to screensharing"); + } + m_pSoftwareCursorTimer->updateTimeout(std::chrono::seconds(1)); } if (!PFRAME->withDamage) diff --git a/src/protocols/Screencopy.hpp b/src/protocols/Screencopy.hpp index 7b9a5770..1bdf6963 100644 --- a/src/protocols/Screencopy.hpp +++ b/src/protocols/Screencopy.hpp @@ -7,6 +7,7 @@ #include #include "../managers/HookSystemManager.hpp" #include "../helpers/Timer.hpp" +#include "../managers/eventLoop/EventLoopTimer.hpp" class CMonitor; @@ -84,6 +85,9 @@ class CScreencopyProtocolManager { std::list m_lFrames; std::list m_lClients; + SP m_pSoftwareCursorTimer; + bool m_bTimerArmed = false; + wl_listener m_liDisplayDestroy; std::vector m_vFramesAwaitingWrite;