mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2025-10-29 11:36:04 +00:00
portals: Fix use of a potentially destroyed session (#355)
This commit is contained in:
parent
371b96bd11
commit
add72858d1
@ -41,13 +41,14 @@ dbUasv CScreencopyPortal::onCreateSession(sdbus::ObjectPath requestHandle, sdbus
|
||||
Debug::log(LOG, "[screencopy] | {}", sessionHandle.c_str());
|
||||
Debug::log(LOG, "[screencopy] | appid: {}", appID);
|
||||
|
||||
const auto PSESSION = m_vSessions.emplace_back(std::make_unique<SSession>(appID, requestHandle, sessionHandle)).get();
|
||||
const Hyprutils::Memory::CWeakPointer<SSession> PSESSION = m_vSessions.emplace_back(Hyprutils::Memory::makeUnique<SSession>(appID, requestHandle, sessionHandle));
|
||||
PSESSION->self = PSESSION;
|
||||
|
||||
// create objects
|
||||
PSESSION->session = createDBusSession(sessionHandle);
|
||||
PSESSION->session->onDestroy = [PSESSION, this]() {
|
||||
if (PSESSION->sharingData.active) {
|
||||
m_pPipewire->destroyStream(PSESSION);
|
||||
m_pPipewire->destroyStream(PSESSION.get());
|
||||
Debug::log(LOG, "[screencopy] Stream destroyed");
|
||||
}
|
||||
PSESSION->session.release();
|
||||
@ -346,8 +347,10 @@ void CScreencopyPortal::SSession::startCopy() {
|
||||
|
||||
void CScreencopyPortal::SSession::initCallbacks() {
|
||||
if (sharingData.frameCallback) {
|
||||
sharingData.frameCallback->setBuffer([this](CCZwlrScreencopyFrameV1* r, uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||
Debug::log(TRACE, "[sc] wlrOnBuffer for {}", (void*)this);
|
||||
sharingData.frameCallback->setBuffer([this, self = self](CCZwlrScreencopyFrameV1* r, uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||
Debug::log(TRACE, "[sc] wlrOnBuffer for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
sharingData.frameInfoSHM.w = width;
|
||||
sharingData.frameInfoSHM.h = height;
|
||||
@ -357,8 +360,10 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
|
||||
// todo: done if ver < 3
|
||||
});
|
||||
sharingData.frameCallback->setReady([this](CCZwlrScreencopyFrameV1* r, uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) {
|
||||
Debug::log(TRACE, "[sc] wlrOnReady for {}", (void*)this);
|
||||
sharingData.frameCallback->setReady([this, self = self](CCZwlrScreencopyFrameV1* r, uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) {
|
||||
Debug::log(TRACE, "[sc] wlrOnReady for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
sharingData.status = FRAME_READY;
|
||||
|
||||
@ -375,12 +380,16 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
|
||||
sharingData.frameCallback.reset();
|
||||
});
|
||||
sharingData.frameCallback->setFailed([this](CCZwlrScreencopyFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] wlrOnFailed for {}", (void*)this);
|
||||
sharingData.frameCallback->setFailed([this, self = self](CCZwlrScreencopyFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] wlrOnFailed for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
sharingData.status = FRAME_FAILED;
|
||||
});
|
||||
sharingData.frameCallback->setDamage([this](CCZwlrScreencopyFrameV1* r, uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] wlrOnDamage for {}", (void*)this);
|
||||
sharingData.frameCallback->setDamage([this, self = self](CCZwlrScreencopyFrameV1* r, uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] wlrOnDamage for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
if (sharingData.damageCount > 3) {
|
||||
sharingData.damage[0] = {0, 0, sharingData.frameInfoDMA.w, sharingData.frameInfoDMA.h};
|
||||
@ -391,15 +400,19 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
|
||||
Debug::log(TRACE, "[sc] wlr damage: {} {} {} {}", x, y, width, height);
|
||||
});
|
||||
sharingData.frameCallback->setLinuxDmabuf([this](CCZwlrScreencopyFrameV1* r, uint32_t format, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] wlrOnDmabuf for {}", (void*)this);
|
||||
sharingData.frameCallback->setLinuxDmabuf([this, self = self](CCZwlrScreencopyFrameV1* r, uint32_t format, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] wlrOnDmabuf for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
sharingData.frameInfoDMA.w = width;
|
||||
sharingData.frameInfoDMA.h = height;
|
||||
sharingData.frameInfoDMA.fmt = format;
|
||||
});
|
||||
sharingData.frameCallback->setBufferDone([this](CCZwlrScreencopyFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] wlrOnBufferDone for {}", (void*)this);
|
||||
sharingData.frameCallback->setBufferDone([this, self = self](CCZwlrScreencopyFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] wlrOnBufferDone for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
const auto PSTREAM = g_pPortalManager->m_sPortals.screencopy->m_pPipewire->streamFromSession(this);
|
||||
|
||||
@ -449,8 +462,10 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
Debug::log(TRACE, "[sc] wlr frame copied");
|
||||
});
|
||||
} else if (sharingData.windowFrameCallback) {
|
||||
sharingData.windowFrameCallback->setBuffer([this](CCHyprlandToplevelExportFrameV1* r, uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||
Debug::log(TRACE, "[sc] hlOnBuffer for {}", (void*)this);
|
||||
sharingData.windowFrameCallback->setBuffer([this, self = self](CCHyprlandToplevelExportFrameV1* r, uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||
Debug::log(TRACE, "[sc] hlOnBuffer for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
sharingData.frameInfoSHM.w = width;
|
||||
sharingData.frameInfoSHM.h = height;
|
||||
@ -460,8 +475,10 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
|
||||
// todo: done if ver < 3
|
||||
});
|
||||
sharingData.windowFrameCallback->setReady([this](CCHyprlandToplevelExportFrameV1* r, uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) {
|
||||
Debug::log(TRACE, "[sc] hlOnReady for {}", (void*)this);
|
||||
sharingData.windowFrameCallback->setReady([this, self = self](CCHyprlandToplevelExportFrameV1* r, uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) {
|
||||
Debug::log(TRACE, "[sc] hlOnReady for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
sharingData.status = FRAME_READY;
|
||||
|
||||
@ -478,12 +495,16 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
|
||||
sharingData.windowFrameCallback.reset();
|
||||
});
|
||||
sharingData.windowFrameCallback->setFailed([this](CCHyprlandToplevelExportFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] hlOnFailed for {}", (void*)this);
|
||||
sharingData.windowFrameCallback->setFailed([this, self = self](CCHyprlandToplevelExportFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] hlOnFailed for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
sharingData.status = FRAME_FAILED;
|
||||
});
|
||||
sharingData.windowFrameCallback->setDamage([this](CCHyprlandToplevelExportFrameV1* r, uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] hlOnDamage for {}", (void*)this);
|
||||
sharingData.windowFrameCallback->setDamage([this, self = self](CCHyprlandToplevelExportFrameV1* r, uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] hlOnDamage for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
if (sharingData.damageCount > 3) {
|
||||
sharingData.damage[0] = {0, 0, sharingData.frameInfoDMA.w, sharingData.frameInfoDMA.h};
|
||||
@ -494,15 +515,19 @@ void CScreencopyPortal::SSession::initCallbacks() {
|
||||
|
||||
Debug::log(TRACE, "[sc] hl damage: {} {} {} {}", x, y, width, height);
|
||||
});
|
||||
sharingData.windowFrameCallback->setLinuxDmabuf([this](CCHyprlandToplevelExportFrameV1* r, uint32_t format, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] hlOnDmabuf for {}", (void*)this);
|
||||
sharingData.windowFrameCallback->setLinuxDmabuf([this, self = self](CCHyprlandToplevelExportFrameV1* r, uint32_t format, uint32_t width, uint32_t height) {
|
||||
Debug::log(TRACE, "[sc] hlOnDmabuf for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
sharingData.frameInfoDMA.w = width;
|
||||
sharingData.frameInfoDMA.h = height;
|
||||
sharingData.frameInfoDMA.fmt = format;
|
||||
});
|
||||
sharingData.windowFrameCallback->setBufferDone([this](CCHyprlandToplevelExportFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] hlOnBufferDone for {}", (void*)this);
|
||||
sharingData.windowFrameCallback->setBufferDone([this, self = self](CCHyprlandToplevelExportFrameV1* r) {
|
||||
Debug::log(TRACE, "[sc] hlOnBufferDone for {}", (void*)self.get());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
const auto PSTREAM = g_pPortalManager->m_sPortals.screencopy->m_pPipewire->streamFromSession(this);
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
#include "wlr-screencopy-unstable-v1.hpp"
|
||||
#include "hyprland-toplevel-export-v1.hpp"
|
||||
#include <hyprutils/memory/UniquePtr.hpp>
|
||||
#include <hyprutils/memory/WeakPtr.hpp>
|
||||
#include <sdbus-c++/sdbus-c++.h>
|
||||
#include "../shared/ScreencopyShared.hpp"
|
||||
#include <gbm.h>
|
||||
@ -62,17 +64,18 @@ class CScreencopyPortal {
|
||||
std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
|
||||
struct SSession {
|
||||
std::string appid;
|
||||
sdbus::ObjectPath requestHandle, sessionHandle;
|
||||
uint32_t cursorMode = HIDDEN;
|
||||
uint32_t persistMode = 0;
|
||||
std::string appid;
|
||||
sdbus::ObjectPath requestHandle, sessionHandle;
|
||||
uint32_t cursorMode = HIDDEN;
|
||||
uint32_t persistMode = 0;
|
||||
|
||||
std::unique_ptr<SDBusRequest> request;
|
||||
std::unique_ptr<SDBusSession> session;
|
||||
SSelectionData selection;
|
||||
std::unique_ptr<SDBusRequest> request;
|
||||
std::unique_ptr<SDBusSession> session;
|
||||
SSelectionData selection;
|
||||
Hyprutils::Memory::CWeakPointer<SSession> self;
|
||||
|
||||
void startCopy();
|
||||
void initCallbacks();
|
||||
void startCopy();
|
||||
void initCallbacks();
|
||||
|
||||
struct {
|
||||
bool active = false;
|
||||
@ -113,12 +116,12 @@ class CScreencopyPortal {
|
||||
std::unique_ptr<CPipewireConnection> m_pPipewire;
|
||||
|
||||
private:
|
||||
std::unique_ptr<sdbus::IObject> m_pObject;
|
||||
std::unique_ptr<sdbus::IObject> m_pObject;
|
||||
|
||||
std::vector<std::unique_ptr<SSession>> m_vSessions;
|
||||
std::vector<Hyprutils::Memory::CUniquePointer<SSession>> m_vSessions;
|
||||
|
||||
SSession* getSession(sdbus::ObjectPath& path);
|
||||
void startSharing(SSession* pSession);
|
||||
SSession* getSession(sdbus::ObjectPath& path);
|
||||
void startSharing(SSession* pSession);
|
||||
|
||||
struct {
|
||||
SP<CCZwlrScreencopyManagerV1> screencopy = nullptr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user