From b0528e0cf7c67d4ae17967bd50fbebb919006f4f Mon Sep 17 00:00:00 2001 From: jp9000 Date: Tue, 8 Feb 2022 11:07:23 -0800 Subject: [PATCH] UI: Fix properties view crash with non-obs objects The properties view incorrectly assumed that it was being used with obs objects only. (Jim note: I'm annoyed.) --- UI/properties-view.cpp | 44 +++++++++++++++++++++++++++++++++--------- UI/properties-view.hpp | 23 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/UI/properties-view.cpp b/UI/properties-view.cpp index 5e20b7e801713d..87a438f6ac9883 100644 --- a/UI/properties-view.cpp +++ b/UI/properties-view.cpp @@ -89,10 +89,11 @@ Q_DECLARE_METATYPE(media_frames_per_second); void OBSPropertiesView::ReloadProperties() { - if (weakObj) { - OBSObject obj = GetObject(); + if (weakObj || rawObj) { + OBSObject strongObj = GetObject(); + void *obj = strongObj ? strongObj.Get() : rawObj; if (obj) - properties.reset(reloadCallback(obj.Get())); + properties.reset(reloadCallback(obj)); } else { properties.reset(reloadCallback((void *)type.c_str())); obs_properties_apply_settings(properties.get(), settings); @@ -176,6 +177,24 @@ void OBSPropertiesView::GetScrollPos(int &h, int &v) v = scroll->value(); } +OBSPropertiesView::OBSPropertiesView(OBSData settings_, obs_object_t *obj, + PropertiesReloadCallback reloadCallback, + PropertiesUpdateCallback callback_, + PropertiesVisualUpdateCb cb_, int minSize_) + : VScrollArea(nullptr), + properties(nullptr, obs_properties_destroy), + settings(settings_), + weakObj(obs_object_get_weak_object(obj)), + reloadCallback(reloadCallback), + callback(callback_), + cb(cb_), + minSize(minSize_) +{ + setFrameShape(QFrame::NoFrame); + QMetaObject::invokeMethod(this, "ReloadProperties", + Qt::QueuedConnection); +} + OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj, PropertiesReloadCallback reloadCallback, PropertiesUpdateCallback callback_, @@ -183,7 +202,7 @@ OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj, : VScrollArea(nullptr), properties(nullptr, obs_properties_destroy), settings(settings_), - weakObj(obs_object_get_weak_object((obs_object_t *)obj)), + rawObj(obj), reloadCallback(reloadCallback), callback(callback_), cb(cb_), @@ -1907,9 +1926,13 @@ void WidgetInfo::ButtonClicked() } return; } - if (obs_property_button_clicked(property, view->GetObject())) { - QMetaObject::invokeMethod(view, "RefreshProperties", - Qt::QueuedConnection); + if (view->rawObj || view->weakObj) { + OBSObject strongObj = view->GetObject(); + void *obj = strongObj ? strongObj.Get() : view->rawObj; + if (obs_property_button_clicked(property, obj)) { + QMetaObject::invokeMethod(view, "RefreshProperties", + Qt::QueuedConnection); + } } } @@ -1983,7 +2006,9 @@ void WidgetInfo::ControlChanged() update_timer = new QTimer; connect(update_timer, &QTimer::timeout, [this, &ru = recently_updated]() { - OBSObject obj = view->GetObject(); + OBSObject strongObj = view->GetObject(); + void *obj = strongObj ? strongObj.Get() + : view->rawObj; if (obj && view->callback && !view->deferUpdate) { view->callback(obj, old_settings_cache, @@ -2004,7 +2029,8 @@ void WidgetInfo::ControlChanged() } if (view->cb && !view->deferUpdate) { - OBSObject obj = view->GetObject(); + OBSObject strongObj = view->GetObject(); + void *obj = strongObj ? strongObj.Get() : view->rawObj; if (obj) view->cb(obj, view->settings); } diff --git a/UI/properties-view.hpp b/UI/properties-view.hpp index e6e628abfe67b9..0e460094df3603 100644 --- a/UI/properties-view.hpp +++ b/UI/properties-view.hpp @@ -98,6 +98,7 @@ class OBSPropertiesView : public VScrollArea { properties_t properties; OBSData settings; OBSWeakObjectAutoRelease weakObj; + void *rawObj; std::string type; PropertiesReloadCallback reloadCallback; PropertiesUpdateCallback callback = nullptr; @@ -152,6 +153,11 @@ public slots: void PropertiesRefreshed(); public: + OBSPropertiesView(OBSData settings, obs_object_t *obj, + PropertiesReloadCallback reloadCallback, + PropertiesUpdateCallback callback, + PropertiesVisualUpdateCb cb = nullptr, + int minSize = 0); OBSPropertiesView(OBSData settings, void *obj, PropertiesReloadCallback reloadCallback, PropertiesUpdateCallback callback, @@ -161,6 +167,23 @@ public slots: PropertiesReloadCallback reloadCallback, int minSize = 0); +#define obj_constructor(type) \ + inline OBSPropertiesView(OBSData settings, obs_##type##_t *type, \ + PropertiesReloadCallback reloadCallback, \ + PropertiesUpdateCallback callback, \ + PropertiesVisualUpdateCb cb = nullptr, \ + int minSize = 0) \ + : OBSPropertiesView(settings, (obs_object_t *)type, \ + reloadCallback, callback, cb, minSize) \ + { \ + } + + obj_constructor(source); + obj_constructor(output); + obj_constructor(encoder); + obj_constructor(service); +#undef obj_constructor + inline obs_data_t *GetSettings() const { return settings; } inline void UpdateSettings()