UI: Use weak source for projectors

The projectors were holding on to a reference of a source, even
if the source was deleted.
This commit is contained in:
cg2121 2022-03-11 04:05:11 -06:00 committed by Ryan Foster
parent 9116ceab6e
commit 0553ddcec0
2 changed files with 16 additions and 12 deletions

View file

@ -16,11 +16,12 @@ static bool updatingMultiview = false, mouseSwitching, transitionOnDoubleClick;
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
ProjectorType type_) ProjectorType type_)
: OBSQTDisplay(widget, Qt::Window), : OBSQTDisplay(widget, Qt::Window), weakSource(OBSGetWeakRef(source_))
source(source_),
removedSignal(obs_source_get_signal_handler(source), "remove",
OBSSourceRemoved, this)
{ {
OBSSource source = GetSource();
destroyedSignal.Connect(obs_source_get_signal_handler(source),
"destroy", OBSSourceDestroyed, this);
isAlwaysOnTop = config_get_bool(GetGlobalConfig(), "BasicWindow", isAlwaysOnTop = config_get_bool(GetGlobalConfig(), "BasicWindow",
"ProjectorAlwaysOnTop"); "ProjectorAlwaysOnTop");
@ -103,6 +104,7 @@ OBSProjector::~OBSProjector()
GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender, GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender,
this); this);
OBSSource source = GetSource();
if (source) if (source)
obs_source_dec_showing(source); obs_source_dec_showing(source);
@ -157,7 +159,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
return; return;
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow()); OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSSource source = window->source; OBSSource source = window->GetSource();
uint32_t targetCX; uint32_t targetCX;
uint32_t targetCY; uint32_t targetCY;
@ -191,11 +193,11 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
obs_source_dec_showing(source); obs_source_dec_showing(source);
obs_source_inc_showing(curSource); obs_source_inc_showing(curSource);
source = curSource; source = curSource;
window->source = source; window->weakSource = OBSGetWeakRef(source);
} }
} else if (window->type == ProjectorType::Preview && } else if (window->type == ProjectorType::Preview &&
!main->IsPreviewProgramMode()) { !main->IsPreviewProgramMode()) {
window->source = nullptr; window->weakSource = nullptr;
} }
if (source) if (source)
@ -206,7 +208,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
endRegion(); endRegion();
} }
void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params) void OBSProjector::OBSSourceDestroyed(void *data, calldata_t *params)
{ {
OBSProjector *window = reinterpret_cast<OBSProjector *>(data); OBSProjector *window = reinterpret_cast<OBSProjector *>(data);
QMetaObject::invokeMethod(window, "EscapeTriggered"); QMetaObject::invokeMethod(window, "EscapeTriggered");
@ -367,7 +369,7 @@ void OBSProjector::UpdateProjectorTitle(QString name)
OBSSource OBSProjector::GetSource() OBSSource OBSProjector::GetSource()
{ {
return source; return OBSGetStrongRef(weakSource);
} }
ProjectorType OBSProjector::GetProjectorType() ProjectorType OBSProjector::GetProjectorType()
@ -410,6 +412,7 @@ void OBSProjector::OpenFullScreenProjector()
int monitor = sender()->property("monitor").toInt(); int monitor = sender()->property("monitor").toInt();
SetMonitor(monitor); SetMonitor(monitor);
OBSSource source = GetSource();
UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source))); UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source)));
} }
@ -426,6 +429,7 @@ void OBSProjector::OpenWindowedProjector()
savedMonitor = -1; savedMonitor = -1;
OBSSource source = GetSource();
UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source))); UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source)));
screen = nullptr; screen = nullptr;
} }

View file

@ -18,12 +18,12 @@ class OBSProjector : public OBSQTDisplay {
Q_OBJECT Q_OBJECT
private: private:
OBSSource source; OBSWeakSourceAutoRelease weakSource;
OBSSignal removedSignal; OBSSignal destroyedSignal;
static void OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy); static void OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy);
static void OBSRender(void *data, uint32_t cx, uint32_t cy); static void OBSRender(void *data, uint32_t cx, uint32_t cy);
static void OBSSourceRemoved(void *data, calldata_t *params); static void OBSSourceDestroyed(void *data, calldata_t *params);
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override;