screenshare: improve destroy logic of objects (#13554)
This commit is contained in:
parent
34c7cc7d38
commit
803e81ac39
7 changed files with 24 additions and 46 deletions
|
|
@ -145,17 +145,13 @@ WP<CScreenshareSession> CScreenshareManager::getManagedSession(eScreenshareType
|
|||
auto& session = *it;
|
||||
|
||||
session->stoppedListener = session->m_session->m_events.stopped.listen([session = WP<SManagedSession>(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)
|
||||
|
|
|
|||
|
|
@ -206,8 +206,6 @@ namespace Screenshare {
|
|||
|
||||
UP<CCursorshareSession> newCursorSession(wl_client* client, WP<CWLPointerResource> pointer);
|
||||
|
||||
void destroyClientSessions(wl_client* client);
|
||||
|
||||
void onOutputCommit(PHLMONITOR monitor);
|
||||
bool isOutputBeingSSd(PHLMONITOR monitor);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<CEventLoopTimer>(
|
||||
std::chrono::milliseconds(500),
|
||||
[this](SP<CEventLoopTimer> 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) {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ CScreencopyClient::CScreencopyClient(SP<CZwlrScreencopyManagerV1> 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<CZwlrScreencopyManagerV1> 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<CZwlrScreencopyFrameV1> resource_, WP<CScr
|
|||
m_resource->setCopy([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");
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ namespace Screenshare {
|
|||
class CScreencopyClient {
|
||||
public:
|
||||
CScreencopyClient(SP<CZwlrScreencopyManagerV1> 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;
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ CToplevelExportClient::CToplevelExportClient(SP<CHyprlandToplevelExportManagerV1
|
|||
if UNLIKELY (!good())
|
||||
return;
|
||||
|
||||
m_resource->setOnDestroy([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(SP<CHyprlandToplevelExportManagerV1
|
|||
m_savedClient = m_resource->client();
|
||||
}
|
||||
|
||||
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<CHyprlandToplevelExportFrameV1> 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");
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ namespace Screenshare {
|
|||
class CToplevelExportClient {
|
||||
public:
|
||||
CToplevelExportClient(SP<CHyprlandToplevelExportManagerV1> 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue