diff --git a/src/managers/screenshare/ScreenshareManager.cpp b/src/managers/screenshare/ScreenshareManager.cpp index 57b9f6ef..70e2bf5e 100644 --- a/src/managers/screenshare/ScreenshareManager.cpp +++ b/src/managers/screenshare/ScreenshareManager.cpp @@ -145,17 +145,13 @@ WP CScreenshareManager::getManagedSession(eScreenshareType auto& session = *it; session->stoppedListener = session->m_session->m_events.stopped.listen([session = WP(session)]() { - std::erase_if(Screenshare::mgr()->m_managedSessions, [&](const auto& s) { return !s || session.expired() || s->m_session == session->m_session; }); + if (!session.expired()) + std::erase_if(Screenshare::mgr()->m_managedSessions, [&](const auto& s) { return s && s->m_session.get() == session->m_session.get(); }); }); return session->m_session; } -void CScreenshareManager::destroyClientSessions(wl_client* client) { - LOGM(Log::TRACE, "Destroy client sessions for {:x}", (uintptr_t)client); - std::erase_if(m_managedSessions, [&](const auto& session) { return !session || session->m_session->m_client == client; }); -} - bool CScreenshareManager::isOutputBeingSSd(PHLMONITOR monitor) { return std::ranges::any_of(m_pendingFrames, [monitor](const auto& f) { if (!f || !f->m_session) diff --git a/src/managers/screenshare/ScreenshareManager.hpp b/src/managers/screenshare/ScreenshareManager.hpp index afd35426..d62585ae 100644 --- a/src/managers/screenshare/ScreenshareManager.hpp +++ b/src/managers/screenshare/ScreenshareManager.hpp @@ -206,8 +206,6 @@ namespace Screenshare { UP newCursorSession(wl_client* client, WP pointer); - void destroyClientSessions(wl_client* client); - void onOutputCommit(PHLMONITOR monitor); bool isOutputBeingSSd(PHLMONITOR monitor); diff --git a/src/managers/screenshare/ScreenshareSession.cpp b/src/managers/screenshare/ScreenshareSession.cpp index 5c5875a8..2fddc431 100644 --- a/src/managers/screenshare/ScreenshareSession.cpp +++ b/src/managers/screenshare/ScreenshareSession.cpp @@ -39,7 +39,8 @@ CScreenshareSession::CScreenshareSession(PHLMONITOR monitor, CBox captureRegion, CScreenshareSession::~CScreenshareSession() { stop(); - LOGM(Log::TRACE, "Destroyed screenshare session for ({}): {}", m_type, m_name); + uintptr_t ptr = m_type == SHARE_WINDOW && !m_window.expired() ? (uintptr_t)m_window.get() : (m_monitor.expired() ? (uintptr_t)nullptr : (uintptr_t)m_monitor.get()); + LOGM(Log::TRACE, "Destroyed screenshare session for ({}): {}, {:x}", m_type, m_name, ptr); } void CScreenshareSession::stop() { @@ -52,6 +53,9 @@ void CScreenshareSession::stop() { } void CScreenshareSession::init() { + uintptr_t ptr = m_type == SHARE_WINDOW && !m_window.expired() ? (uintptr_t)m_window.get() : (m_monitor.expired() ? (uintptr_t)nullptr : (uintptr_t)m_monitor.get()); + LOGM(Log::TRACE, "Created screenshare session for ({}): {}, {:x}", m_type, m_name, ptr); + m_shareStopTimer = makeShared( std::chrono::milliseconds(500), [this](SP self, void* data) { @@ -121,7 +125,7 @@ void CScreenshareSession::screenshareEvents(bool startSharing) { m_sharing = true; g_pEventManager->postEvent(SHyprIPCEvent{.event = "screencast", .data = std::format("1,{}", m_type)}); g_pEventManager->postEvent(SHyprIPCEvent{.event = "screencastv2", .data = std::format("1,{},{}", m_type, m_name)}); - LOGM(Log::INFO, "New screenshare session for ({}): {}", m_type, m_name); + LOGM(Log::INFO, "Started screenshare session for ({}): {}", m_type, m_name); Event::bus()->m_events.screenshare.state.emit(true, m_type, m_name); } else if (!startSharing && m_sharing) { diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 5cc884de..825939ef 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -13,10 +13,7 @@ CScreencopyClient::CScreencopyClient(SP resource_) : m return; m_resource->setDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); }); - m_resource->setOnDestroy([this](CZwlrScreencopyManagerV1* pMgr) { - Screenshare::mgr()->destroyClientSessions(m_savedClient); - PROTO::screencopy->destroyResource(this); - }); + m_resource->setOnDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); }); m_resource->setCaptureOutput( [this](CZwlrScreencopyManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* output) { captureOutput(frame, overlayCursor, output, {}); }); m_resource->setCaptureOutputRegion([this](CZwlrScreencopyManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* output, int32_t x, int32_t y, int32_t w, @@ -25,10 +22,6 @@ CScreencopyClient::CScreencopyClient(SP resource_) : m m_savedClient = m_resource->client(); } -CScreencopyClient::~CScreencopyClient() { - Screenshare::mgr()->destroyClientSessions(m_savedClient); -} - void CScreencopyClient::captureOutput(uint32_t frame, int32_t overlayCursor_, wl_resource* output, CBox box) { const auto PMONITORRES = CWLOutputResource::fromResource(output); if (!PMONITORRES || !PMONITORRES->m_monitor) { @@ -69,11 +62,6 @@ CScreencopyFrame::CScreencopyFrame(SP resource_, WPsetCopy([this](CZwlrScreencopyFrameV1* pFrame, wl_resource* res) { shareFrame(pFrame, res, false); }); m_resource->setCopyWithDamage([this](CZwlrScreencopyFrameV1* pFrame, wl_resource* res) { shareFrame(pFrame, res, true); }); - m_listeners.stopped = m_session->m_events.stopped.listen([this]() { - if (good()) - m_resource->sendFailed(); - }); - m_frame = m_session->nextFrame(overlayCursor); auto formats = m_session->allowedFormats(); @@ -111,6 +99,12 @@ void CScreencopyFrame::shareFrame(CZwlrScreencopyFrameV1* pFrame, wl_resource* b return; } + if UNLIKELY (m_session.expired() || !m_session->monitor()) { + LOGM(Log::ERR, "Session stopped for frame {:x}", (uintptr_t)this); + m_resource->sendFailed(); + return; + } + if UNLIKELY (m_buffer) { LOGM(Log::ERR, "Buffer used in {:x}", (uintptr_t)this); m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_ALREADY_USED, "frame already used"); diff --git a/src/protocols/Screencopy.hpp b/src/protocols/Screencopy.hpp index 3659c753..b73c090d 100644 --- a/src/protocols/Screencopy.hpp +++ b/src/protocols/Screencopy.hpp @@ -19,7 +19,6 @@ namespace Screenshare { class CScreencopyClient { public: CScreencopyClient(SP resource_); - ~CScreencopyClient(); bool good(); @@ -52,10 +51,7 @@ class CScreencopyFrame { Time::steady_tp m_timestamp; bool m_overlayCursor = true; - struct { - CHyprSignalListener stopped; - } m_listeners; - + // void shareFrame(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer, bool withDamage); friend class CScreencopyProtocol; diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index bf553a92..d7ba7519 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -13,10 +13,7 @@ CToplevelExportClient::CToplevelExportClient(SPsetOnDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { - Screenshare::mgr()->destroyClientSessions(m_savedClient); - PROTO::toplevelExport->destroyResource(this); - }); + m_resource->setOnDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); }); m_resource->setDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); }); m_resource->setCaptureToplevel([this](CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, uint32_t handle) { captureToplevel(frame, overlayCursor, g_pCompositor->getWindowFromHandle(handle)); @@ -28,10 +25,6 @@ CToplevelExportClient::CToplevelExportClient(SPclient(); } -CToplevelExportClient::~CToplevelExportClient() { - Screenshare::mgr()->destroyClientSessions(m_savedClient); -} - void CToplevelExportClient::captureToplevel(uint32_t frame, int32_t overlayCursor_, PHLWINDOW handle) { auto session = Screenshare::mgr()->getManagedSession(m_resource->client(), handle); @@ -63,11 +56,6 @@ CToplevelExportFrame::CToplevelExportFrame(SP re m_resource->setDestroy([this](CHyprlandToplevelExportFrameV1* pFrame) { PROTO::toplevelExport->destroyResource(this); }); m_resource->setCopy([this](CHyprlandToplevelExportFrameV1* pFrame, wl_resource* res, int32_t ignoreDamage) { shareFrame(res, !!ignoreDamage); }); - m_listeners.stopped = m_session->m_events.stopped.listen([this]() { - if (good()) - m_resource->sendFailed(); - }); - m_frame = m_session->nextFrame(overlayCursor); auto formats = m_session->allowedFormats(); @@ -100,6 +88,12 @@ void CToplevelExportFrame::shareFrame(wl_resource* buffer, bool ignoreDamage) { return; } + if UNLIKELY (m_session.expired() || !m_session->monitor()) { + LOGM(Log::ERR, "Session stopped for frame {:x}", (uintptr_t)this); + m_resource->sendFailed(); + return; + } + if UNLIKELY (m_buffer) { LOGM(Log::ERR, "Buffer used in {:x}", (uintptr_t)this); m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_ALREADY_USED, "frame already used"); diff --git a/src/protocols/ToplevelExport.hpp b/src/protocols/ToplevelExport.hpp index 38dec784..5d30f09b 100644 --- a/src/protocols/ToplevelExport.hpp +++ b/src/protocols/ToplevelExport.hpp @@ -18,7 +18,6 @@ namespace Screenshare { class CToplevelExportClient { public: CToplevelExportClient(SP resource_); - ~CToplevelExportClient(); bool good(); @@ -50,10 +49,7 @@ class CToplevelExportFrame { CHLBufferReference m_buffer; Time::steady_tp m_timestamp; - struct { - CHyprSignalListener stopped; - } m_listeners; - + // void shareFrame(wl_resource* buffer, bool ignoreDamage); friend class CToplevelExportProtocol;