Ver código fonte

UI: Migrate undo/redo to using UUIDs

derrod 2 anos atrás
pai
commit
67f7712d83

+ 29 - 23
UI/adv-audio-control.cpp

@@ -440,19 +440,19 @@ void OBSAdvAudioCtrl::volumeChanged(double db)
 	float val = obs_db_to_mul(db);
 	obs_source_set_volume(source, val);
 
-	auto undo_redo = [](const std::string &name, float val) {
+	auto undo_redo = [](const std::string &uuid, float val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_volume(source, val);
 	};
 
 	const char *name = obs_source_get_name(source);
-
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic *main = OBSBasic::Get();
 	main->undo_s.add_action(
 		QTStr("Undo.Volume.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, val), name, name,
+		std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
 		true);
 }
 
@@ -463,17 +463,18 @@ void OBSAdvAudioCtrl::percentChanged(int percent)
 
 	obs_source_set_volume(source, val);
 
-	auto undo_redo = [](const std::string &name, float val) {
+	auto undo_redo = [](const std::string &uuid, float val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_volume(source, val);
 	};
 
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		QTStr("Undo.Volume.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, val), name, name,
+		std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
 		true);
 }
 
@@ -502,19 +503,20 @@ void OBSAdvAudioCtrl::downmixMonoChanged(bool val)
 
 	obs_source_set_flags(source, flags);
 
-	auto undo_redo = [](const std::string &name, bool val) {
+	auto undo_redo = [](const std::string &uuid, bool val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		set_mono(source, val);
 	};
 
 	QString text = QTStr(val ? "Undo.ForceMono.On" : "Undo.ForceMono.Off");
 
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		text.arg(name),
 		std::bind(undo_redo, std::placeholders::_1, !val),
-		std::bind(undo_redo, std::placeholders::_1, val), name, name);
+		std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid);
 }
 
 void OBSAdvAudioCtrl::balanceChanged(int val)
@@ -531,17 +533,18 @@ void OBSAdvAudioCtrl::balanceChanged(int val)
 
 	obs_source_set_balance_value(source, bal);
 
-	auto undo_redo = [](const std::string &name, float val) {
+	auto undo_redo = [](const std::string &uuid, float val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_balance_value(source, val);
 	};
 
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		QTStr("Undo.Balance.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, bal), name, name,
+		std::bind(undo_redo, std::placeholders::_1, bal), uuid, uuid,
 		true);
 }
 
@@ -560,17 +563,18 @@ void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
 
 	obs_source_set_sync_offset(source, val);
 
-	auto undo_redo = [](const std::string &name, int64_t val) {
+	auto undo_redo = [](const std::string &uuid, int64_t val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_sync_offset(source, val);
 	};
 
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		QTStr("Undo.SyncOffset.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, val), name, name,
+		std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
 		true);
 }
 
@@ -600,16 +604,17 @@ void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
 	blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s",
 	     name ? name : "(null)", type);
 
-	auto undo_redo = [](const std::string &name, obs_monitoring_type val) {
+	auto undo_redo = [](const std::string &uuid, obs_monitoring_type val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_monitoring_type(source, val);
 	};
 
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		QTStr("Undo.MonitoringType.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, mt), name, name);
+		std::bind(undo_redo, std::placeholders::_1, mt), uuid, uuid);
 }
 
 static inline void setMixer(obs_source_t *source, const int mixerIdx,
@@ -625,18 +630,19 @@ static inline void setMixer(obs_source_t *source, const int mixerIdx,
 
 	obs_source_set_audio_mixers(source, new_mixers);
 
-	auto undo_redo = [](const std::string &name, uint32_t mixers) {
+	auto undo_redo = [](const std::string &uuid, uint32_t mixers) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_audio_mixers(source, mixers);
 	};
 
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		QTStr("Undo.Mixers.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, mixers),
-		std::bind(undo_redo, std::placeholders::_1, new_mixers), name,
-		name);
+		std::bind(undo_redo, std::placeholders::_1, new_mixers), uuid,
+		uuid);
 }
 
 void OBSAdvAudioCtrl::mixer1Changed(bool checked)

+ 8 - 8
UI/context-bar-controls.cpp

@@ -40,7 +40,7 @@ void SourceToolbar::SaveOldProperties(obs_source_t *source)
 
 	OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
 	obs_data_apply(oldData, oldSettings);
-	obs_data_set_string(oldData, "undo_sname", obs_source_get_name(source));
+	obs_data_set_string(oldData, "undo_suuid", obs_source_get_uuid(source));
 }
 
 void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
@@ -55,17 +55,17 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
 	OBSSource currentSceneSource = main->GetCurrentSceneSource();
 	if (!currentSceneSource)
 		return;
-	std::string scene_name = obs_source_get_name(currentSceneSource);
-	auto undo_redo = [scene_name = std::move(scene_name),
+	std::string scene_uuid = obs_source_get_uuid(currentSceneSource);
+	auto undo_redo = [scene_uuid = std::move(scene_uuid),
 			  main](const std::string &data) {
 		OBSDataAutoRelease settings =
 			obs_data_create_from_json(data.c_str());
-		OBSSourceAutoRelease source = obs_get_source_by_name(
-			obs_data_get_string(settings, "undo_sname"));
+		OBSSourceAutoRelease source = obs_get_source_by_uuid(
+			obs_data_get_string(settings, "undo_suuid"));
 		obs_source_reset_settings(source, settings);
 
 		OBSSourceAutoRelease scene_source =
-			obs_get_source_by_name(scene_name.c_str());
+			obs_get_source_by_uuid(scene_uuid.c_str());
 		main->SetCurrentScene(scene_source.Get(), true);
 
 		main->UpdateContextBar();
@@ -74,8 +74,8 @@ void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
 	OBSDataAutoRelease new_settings = obs_data_create();
 	OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
 	obs_data_apply(new_settings, curr_settings);
-	obs_data_set_string(new_settings, "undo_sname",
-			    obs_source_get_name(source));
+	obs_data_set_string(new_settings, "undo_suuid",
+			    obs_source_get_uuid(source));
 
 	std::string undo_data(obs_data_get_json(oldData));
 	std::string redo_data(obs_data_get_json(new_settings));

+ 14 - 12
UI/source-tree.cpp

@@ -133,12 +133,13 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 		obs_source_t *scenesource = obs_scene_get_source(scene);
 		int64_t id = obs_sceneitem_get_id(sceneitem);
 		const char *name = obs_source_get_name(scenesource);
+		const char *uuid = obs_source_get_uuid(scenesource);
 		obs_source_t *source = obs_sceneitem_get_source(sceneitem);
 
-		auto undo_redo = [](const std::string &name, int64_t id,
+		auto undo_redo = [](const std::string &uuid, int64_t id,
 				    bool val) {
 			OBSSourceAutoRelease s =
-				obs_get_source_by_name(name.c_str());
+				obs_get_source_by_uuid(uuid.c_str());
 			obs_scene_t *sc = obs_group_or_scene_from_source(s);
 			obs_sceneitem_t *si =
 				obs_scene_find_sceneitem_by_id(sc, id);
@@ -154,7 +155,7 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
 			str.arg(obs_source_get_name(source), name),
 			std::bind(undo_redo, std::placeholders::_1, id, !val),
 			std::bind(undo_redo, std::placeholders::_1, id, val),
-			name, name);
+			uuid, uuid);
 
 		SignalBlocker sourcesSignalBlocker(this);
 		obs_sceneitem_set_visible(sceneitem, val);
@@ -452,32 +453,33 @@ void SourceTreeItem::ExitEditModeInternal(bool save)
 
 	SignalBlocker sourcesSignalBlocker(this);
 	std::string prevName(obs_source_get_name(source));
-	std::string scene_name =
-		obs_source_get_name(main->GetCurrentSceneSource());
-	auto undo = [scene_name, prevName, main](const std::string &data) {
+	std::string scene_uuid =
+		obs_source_get_uuid(main->GetCurrentSceneSource());
+	auto undo = [scene_uuid, prevName, main](const std::string &data) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(data.c_str());
+			obs_get_source_by_uuid(data.c_str());
 		obs_source_set_name(source, prevName.c_str());
 
 		OBSSourceAutoRelease scene_source =
-			obs_get_source_by_name(scene_name.c_str());
+			obs_get_source_by_uuid(scene_uuid.c_str());
 		main->SetCurrentScene(scene_source.Get(), true);
 	};
 
 	std::string editedName = newName;
 
-	auto redo = [scene_name, main, editedName](const std::string &data) {
+	auto redo = [scene_uuid, main, editedName](const std::string &data) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(data.c_str());
+			obs_get_source_by_uuid(data.c_str());
 		obs_source_set_name(source, editedName.c_str());
 
 		OBSSourceAutoRelease scene_source =
-			obs_get_source_by_name(scene_name.c_str());
+			obs_get_source_by_uuid(scene_uuid.c_str());
 		main->SetCurrentScene(scene_source.Get(), true);
 	};
 
+	const char *uuid = obs_source_get_uuid(source);
 	main->undo_s.add_action(QTStr("Undo.Rename").arg(newName.c_str()), undo,
-				redo, newName, prevName);
+				redo, uuid, uuid);
 
 	obs_source_set_name(source, newName.c_str());
 	label->setText(QT_UTF8(newName.c_str()));

+ 9 - 7
UI/volume-control.cpp

@@ -156,9 +156,9 @@ void VolControl::SetMuted(bool)
 			ShowUnassignedWarning(obs_source_get_name(source));
 	}
 
-	auto undo_redo = [](const std::string &name, bool val) {
+	auto undo_redo = [](const std::string &uuid, bool val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_muted(source, val);
 	};
 
@@ -166,11 +166,12 @@ void VolControl::SetMuted(bool)
 		QTStr(checked ? "Undo.Volume.Mute" : "Undo.Volume.Unmute");
 
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		text.arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, checked), name,
-		name);
+		std::bind(undo_redo, std::placeholders::_1, checked), uuid,
+		uuid);
 }
 
 void VolControl::SliderChanged(int vol)
@@ -180,18 +181,19 @@ void VolControl::SliderChanged(int vol)
 	obs_fader_set_deflection(obs_fader, float(vol) / FADER_PRECISION);
 	updateText();
 
-	auto undo_redo = [](const std::string &name, float val) {
+	auto undo_redo = [](const std::string &uuid, float val) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(name.c_str());
+			obs_get_source_by_uuid(uuid.c_str());
 		obs_source_set_volume(source, val);
 	};
 
 	float val = obs_source_get_volume(source);
 	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 	OBSBasic::Get()->undo_s.add_action(
 		QTStr("Undo.Volume.Change").arg(name),
 		std::bind(undo_redo, std::placeholders::_1, prev),
-		std::bind(undo_redo, std::placeholders::_1, val), name, name,
+		std::bind(undo_redo, std::placeholders::_1, val), uuid, uuid,
 		true);
 }
 

+ 79 - 96
UI/window-basic-filters.cpp

@@ -199,34 +199,25 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
 			  obs_data_t *new_settings)
 {
 	obs_source_t *source = reinterpret_cast<obs_source_t *>(vp);
-	obs_source_t *parent = obs_filter_get_parent(source);
-	const char *source_name = obs_source_get_name(source);
+	const char *source_uuid = obs_source_get_uuid(source);
 	OBSBasic *main = OBSBasic::Get();
 
 	OBSDataAutoRelease redo_wrapper = obs_data_create();
-	obs_data_set_string(redo_wrapper, "name", source_name);
+	obs_data_set_string(redo_wrapper, "uuid", source_uuid);
 	obs_data_set_string(redo_wrapper, "settings",
 			    obs_data_get_json(new_settings));
-	obs_data_set_string(redo_wrapper, "parent",
-			    obs_source_get_name(parent));
-
-	OBSDataAutoRelease filter_settings = obs_source_get_settings(source);
 
 	OBSDataAutoRelease undo_wrapper = obs_data_create();
-	obs_data_set_string(undo_wrapper, "name", source_name);
+	obs_data_set_string(undo_wrapper, "uuid", source_uuid);
 	obs_data_set_string(undo_wrapper, "settings",
 			    obs_data_get_json(nd_old_settings));
-	obs_data_set_string(undo_wrapper, "parent",
-			    obs_source_get_name(parent));
 
 	auto undo_redo = [](const std::string &data) {
 		OBSDataAutoRelease dat =
 			obs_data_create_from_json(data.c_str());
-		OBSSourceAutoRelease parent_source = obs_get_source_by_name(
-			obs_data_get_string(dat, "parent"));
-		const char *filter_name = obs_data_get_string(dat, "name");
-		OBSSourceAutoRelease filter = obs_source_get_filter_by_name(
-			parent_source, filter_name);
+		const char *filter_uuid = obs_data_get_string(dat, "uuid");
+		OBSSourceAutoRelease filter =
+			obs_get_source_by_uuid(filter_uuid);
 		OBSDataAutoRelease new_settings = obs_data_create_from_json(
 			obs_data_get_string(dat, "settings"));
 
@@ -240,10 +231,9 @@ void FilterChangeUndoRedo(void *vp, obs_data_t *nd_old_settings,
 
 	main->undo_s.enable();
 
-	std::string name = std::string(obs_source_get_name(source));
 	std::string undo_data = obs_data_get_json(undo_wrapper);
 	std::string redo_data = obs_data_get_json(redo_wrapper);
-	main->undo_s.add_action(QTStr("Undo.Filters").arg(name.c_str()),
+	main->undo_s.add_action(QTStr("Undo.Filters").arg(source_uuid),
 				undo_redo, undo_redo, undo_data, redo_data);
 
 	obs_source_update(source, new_settings);
@@ -602,72 +592,72 @@ void OBSBasicFilters::AddNewFilter(const char *id)
 			return;
 		}
 
-		OBSDataAutoRelease wrapper = obs_data_create();
-		obs_data_set_string(wrapper, "sname",
-				    obs_source_get_name(source));
-		obs_data_set_string(wrapper, "fname", name.c_str());
-		std::string scene_name = obs_source_get_name(
+		OBSSourceAutoRelease filter =
+			obs_source_create(id, name.c_str(), nullptr, nullptr);
+		if (filter) {
+			const char *sourceName = obs_source_get_name(source);
+
+			blog(LOG_INFO,
+			     "User added filter '%s' (%s) to source '%s'",
+			     name.c_str(), id, sourceName);
+
+			obs_source_filter_add(source, filter);
+		} else {
+			blog(LOG_WARNING, "Creating filter '%s' failed!", id);
+			return;
+		}
+
+		std::string parent_uuid(obs_source_get_uuid(source));
+		std::string scene_uuid = obs_source_get_uuid(
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 				->GetCurrentSceneSource());
-		auto undo = [scene_name](const std::string &data) {
-			obs_source_t *ssource =
-				obs_get_source_by_name(scene_name.c_str());
+		/* In order to ensure that the UUID persists through undo/redo,
+		 * we save the source data rather than just recreating the
+		 * source from scratch. */
+		OBSDataAutoRelease rwrapper = obs_save_source(filter);
+		obs_data_set_string(rwrapper, "undo_uuid", parent_uuid.c_str());
+
+		OBSDataAutoRelease uwrapper = obs_data_create();
+		obs_data_set_string(uwrapper, "fname",
+				    obs_source_get_name(filter));
+		obs_data_set_string(uwrapper, "suuid", parent_uuid.c_str());
+
+		auto undo = [scene_uuid](const std::string &data) {
+			OBSSourceAutoRelease ssource =
+				obs_get_source_by_uuid(scene_uuid.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
-				->SetCurrentScene(ssource, true);
-			obs_source_release(ssource);
+				->SetCurrentScene(ssource.Get(), true);
 
-			obs_data_t *dat =
+			OBSDataAutoRelease dat =
 				obs_data_create_from_json(data.c_str());
-			obs_source_t *source = obs_get_source_by_name(
-				obs_data_get_string(dat, "sname"));
-			obs_source_t *filter = obs_source_get_filter_by_name(
-				source, obs_data_get_string(dat, "fname"));
+			OBSSourceAutoRelease source = obs_get_source_by_uuid(
+				obs_data_get_string(dat, "suuid"));
+			OBSSourceAutoRelease filter =
+				obs_source_get_filter_by_name(
+					source,
+					obs_data_get_string(dat, "fname"));
 			obs_source_filter_remove(source, filter);
-
-			obs_data_release(dat);
-			obs_source_release(source);
-			obs_source_release(filter);
 		};
 
-		OBSDataAutoRelease rwrapper = obs_data_create();
-		obs_data_set_string(rwrapper, "sname",
-				    obs_source_get_name(source));
-		auto redo = [scene_name, id = std::string(id),
-			     name](const std::string &data) {
+		auto redo = [scene_uuid](const std::string &data) {
 			OBSSourceAutoRelease ssource =
-				obs_get_source_by_name(scene_name.c_str());
+				obs_get_source_by_uuid(scene_uuid.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 				->SetCurrentScene(ssource.Get(), true);
 
 			OBSDataAutoRelease dat =
 				obs_data_create_from_json(data.c_str());
-			OBSSourceAutoRelease source = obs_get_source_by_name(
-				obs_data_get_string(dat, "sname"));
-
-			OBSSourceAutoRelease filter = obs_source_create(
-				id.c_str(), name.c_str(), nullptr, nullptr);
-			if (filter) {
-				obs_source_filter_add(source, filter);
-			}
+			OBSSourceAutoRelease source = obs_get_source_by_uuid(
+				obs_data_get_string(dat, "undo_uuid"));
+			OBSSourceAutoRelease filter = obs_load_source(dat);
+			obs_source_filter_add(source, filter);
 		};
 
-		std::string undo_data(obs_data_get_json(wrapper));
+		std::string undo_data(obs_data_get_json(uwrapper));
 		std::string redo_data(obs_data_get_json(rwrapper));
-		main->undo_s.add_action(QTStr("Undo.Add").arg(name.c_str()),
-					undo, redo, undo_data, redo_data);
-
-		OBSSourceAutoRelease filter =
-			obs_source_create(id, name.c_str(), nullptr, nullptr);
-		if (filter) {
-			const char *sourceName = obs_source_get_name(source);
-
-			blog(LOG_INFO,
-			     "User added filter '%s' (%s) "
-			     "to source '%s'",
-			     name.c_str(), id, sourceName);
-
-			obs_source_filter_add(source, filter);
-		}
+		main->undo_s.add_action(
+			QTStr("Undo.Add").arg(obs_source_get_name(filter)),
+			undo, redo, undo_data, redo_data, false);
 	}
 }
 
@@ -1111,43 +1101,36 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
 		listItem->setText(QT_UTF8(name.c_str()));
 		obs_source_set_name(filter, name.c_str());
 
-		std::string scene_name = obs_source_get_name(
+		std::string scene_uuid = obs_source_get_uuid(
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 				->GetCurrentSceneSource());
-		auto undo = [scene_name, prev = std::string(prevName),
-			     name](const std::string &data) {
+		auto undo = [scene_uuid, prev = std::string(prevName),
+			     name](const std::string &uuid) {
 			OBSSourceAutoRelease ssource =
-				obs_get_source_by_name(scene_name.c_str());
+				obs_get_source_by_uuid(scene_uuid.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 				->SetCurrentScene(ssource.Get(), true);
 
-			OBSSourceAutoRelease source =
-				obs_get_source_by_name(data.c_str());
 			OBSSourceAutoRelease filter =
-				obs_source_get_filter_by_name(source,
-							      name.c_str());
+				obs_get_source_by_uuid(uuid.c_str());
 			obs_source_set_name(filter, prev.c_str());
 		};
 
-		auto redo = [scene_name, prev = std::string(prevName),
-			     name](const std::string &data) {
+		auto redo = [scene_uuid, prev = std::string(prevName),
+			     name](const std::string &uuid) {
 			OBSSourceAutoRelease ssource =
-				obs_get_source_by_name(scene_name.c_str());
+				obs_get_source_by_uuid(scene_uuid.c_str());
 			reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 				->SetCurrentScene(ssource.Get(), true);
 
-			OBSSourceAutoRelease source =
-				obs_get_source_by_name(data.c_str());
 			OBSSourceAutoRelease filter =
-				obs_source_get_filter_by_name(source,
-							      prev.c_str());
+				obs_get_source_by_uuid(uuid.c_str());
 			obs_source_set_name(filter, name.c_str());
 		};
 
-		std::string undo_data(sourceName);
-		std::string redo_data(sourceName);
+		std::string filter_uuid(obs_source_get_uuid(filter));
 		main->undo_s.add_action(QTStr("Undo.Rename").arg(name.c_str()),
-					undo, redo, undo_data, redo_data);
+					undo, redo, filter_uuid, filter_uuid);
 	}
 
 	listItem->setText(QString());
@@ -1236,39 +1219,39 @@ void OBSBasicFilters::PasteFilter()
 void OBSBasicFilters::delete_filter(OBSSource filter)
 {
 	OBSDataAutoRelease wrapper = obs_save_source(filter);
-	std::string parent_name(obs_source_get_name(source));
-	obs_data_set_string(wrapper, "undo_name", parent_name.c_str());
+	std::string parent_uuid(obs_source_get_uuid(source));
+	obs_data_set_string(wrapper, "undo_uuid", parent_uuid.c_str());
 
-	std::string scene_name = obs_source_get_name(
+	std::string scene_uuid = obs_source_get_uuid(
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			->GetCurrentSceneSource());
-	auto undo = [scene_name](const std::string &data) {
+	auto undo = [scene_uuid](const std::string &data) {
 		OBSSourceAutoRelease ssource =
-			obs_get_source_by_name(scene_name.c_str());
+			obs_get_source_by_uuid(scene_uuid.c_str());
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			->SetCurrentScene(ssource.Get(), true);
 
 		OBSDataAutoRelease dat =
 			obs_data_create_from_json(data.c_str());
-		OBSSourceAutoRelease source = obs_get_source_by_name(
-			obs_data_get_string(dat, "undo_name"));
+		OBSSourceAutoRelease source = obs_get_source_by_uuid(
+			obs_data_get_string(dat, "undo_uuid"));
 		OBSSourceAutoRelease filter = obs_load_source(dat);
 		obs_source_filter_add(source, filter);
 	};
 
 	OBSDataAutoRelease rwrapper = obs_data_create();
 	obs_data_set_string(rwrapper, "fname", obs_source_get_name(filter));
-	obs_data_set_string(rwrapper, "sname", parent_name.c_str());
-	auto redo = [scene_name](const std::string &data) {
+	obs_data_set_string(rwrapper, "suuid", parent_uuid.c_str());
+	auto redo = [scene_uuid](const std::string &data) {
 		OBSSourceAutoRelease ssource =
-			obs_get_source_by_name(scene_name.c_str());
+			obs_get_source_by_uuid(scene_uuid.c_str());
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			->SetCurrentScene(ssource.Get(), true);
 
 		OBSDataAutoRelease dat =
 			obs_data_create_from_json(data.c_str());
-		OBSSourceAutoRelease source = obs_get_source_by_name(
-			obs_data_get_string(dat, "sname"));
+		OBSSourceAutoRelease source = obs_get_source_by_uuid(
+			obs_data_get_string(dat, "suuid"));
 		OBSSourceAutoRelease filter = obs_source_get_filter_by_name(
 			source, obs_data_get_string(dat, "fname"));
 		obs_source_filter_remove(source, filter);

+ 16 - 11
UI/window-basic-main-dropfiles.cpp

@@ -189,32 +189,37 @@ void OBSBasic::AddDropSource(const char *data, DropType image)
 	OBSSourceAutoRelease source =
 		obs_source_create(type, sourceName.c_str(), settings, nullptr);
 	if (source) {
+		OBSDataAutoRelease wrapper = obs_save_source(source);
+
 		OBSScene scene = main->GetCurrentScene();
-		const char *sceneName =
-			obs_source_get_name(obs_scene_get_source(scene));
-		auto undo = [sceneName, sourceName](const std::string &) {
+		std::string sceneUUID =
+			obs_source_get_uuid(obs_scene_get_source(scene));
+		std::string sourceUUID = obs_source_get_uuid(source);
+
+		auto undo = [sceneUUID, sourceUUID](const std::string &) {
 			OBSSourceAutoRelease source =
-				obs_get_source_by_name(sourceName.c_str());
+				obs_get_source_by_uuid(sourceUUID.c_str());
 			obs_source_remove(source);
 			OBSSourceAutoRelease scene =
-				obs_get_source_by_name(sceneName);
+				obs_get_source_by_uuid(sceneUUID.c_str());
 			OBSBasic::Get()->SetCurrentScene(scene.Get(), true);
 		};
-		auto redo = [sceneName, sourceName,
+		auto redo = [sceneUUID, sourceName,
 			     type](const std::string &data) {
 			OBSSourceAutoRelease scene =
-				obs_get_source_by_name(sceneName);
+				obs_get_source_by_uuid(sceneUUID.c_str());
 			OBSBasic::Get()->SetCurrentScene(scene.Get(), true);
-			OBSDataAutoRelease settings =
+
+			OBSDataAutoRelease dat =
 				obs_data_create_from_json(data.c_str());
-			OBSSourceAutoRelease source = obs_source_create(
-				type, sourceName.c_str(), settings, nullptr);
+			OBSSourceAutoRelease source = obs_load_source(dat);
 			obs_scene_add(obs_scene_from_source(scene),
 				      source.Get());
 		};
+
 		undo_s.add_action(QTStr("Undo.Add").arg(sourceName.c_str()),
 				  undo, redo, "",
-				  std::string(obs_data_get_json(settings)));
+				  std::string(obs_data_get_json(wrapper)));
 		obs_scene_add(scene, source);
 	}
 }

+ 7 - 7
UI/window-basic-main-transitions.cpp

@@ -1066,13 +1066,13 @@ void OBSBasic::PasteShowHideTransition(obs_sceneitem_t *item, bool show,
 				       obs_source_t *tr)
 {
 	int64_t sceneItemId = obs_sceneitem_get_id(item);
-	std::string sceneName = obs_source_get_name(
+	std::string sceneUUID = obs_source_get_uuid(
 		obs_scene_get_source(obs_sceneitem_get_scene(item)));
 
-	auto undo_redo = [sceneName, sceneItemId,
+	auto undo_redo = [sceneUUID, sceneItemId,
 			  show](const std::string &data) {
 		OBSSourceAutoRelease source =
-			obs_get_source_by_name(sceneName.c_str());
+			obs_get_source_by_uuid(sceneUUID.c_str());
 		obs_scene_t *scene = obs_scene_from_source(source);
 		obs_sceneitem_t *i =
 			obs_scene_find_sceneitem_by_id(scene, sceneItemId);
@@ -1136,14 +1136,14 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
 		QString id = action->property("transition_id").toString();
 		OBSSceneItem sceneItem = main->GetCurrentSceneItem();
 		int64_t sceneItemId = obs_sceneitem_get_id(sceneItem);
-		std::string sceneName =
-			obs_source_get_name(obs_scene_get_source(
+		std::string sceneUUID =
+			obs_source_get_uuid(obs_scene_get_source(
 				obs_sceneitem_get_scene(sceneItem)));
 
-		auto undo_redo = [sceneName, sceneItemId,
+		auto undo_redo = [sceneUUID, sceneItemId,
 				  visible](const std::string &data) {
 			OBSSourceAutoRelease source =
-				obs_get_source_by_name(sceneName.c_str());
+				obs_get_source_by_uuid(sceneUUID.c_str());
 			obs_scene_t *scene = obs_scene_from_source(source);
 			obs_sceneitem_t *i = obs_scene_find_sceneitem_by_id(
 				scene, sceneItemId);

+ 10 - 11
UI/window-basic-main.cpp

@@ -6632,21 +6632,20 @@ static void RenameListItem(OBSBasic *parent, QListWidget *listWidget,
 		auto undo = [prev = std::string(prevName)](
 				    const std::string &data) {
 			OBSSourceAutoRelease source =
-				obs_get_source_by_name(data.c_str());
+				obs_get_source_by_uuid(data.c_str());
 			obs_source_set_name(source, prev.c_str());
 		};
 
 		auto redo = [name](const std::string &data) {
 			OBSSourceAutoRelease source =
-				obs_get_source_by_name(data.c_str());
+				obs_get_source_by_uuid(data.c_str());
 			obs_source_set_name(source, name.c_str());
 		};
 
-		std::string undo_data(name);
-		std::string redo_data(prevName);
+		std::string source_uuid(obs_source_get_uuid(source));
 		parent->undo_s.add_action(
 			QTStr("Undo.Rename").arg(name.c_str()), undo, redo,
-			undo_data, redo_data);
+			source_uuid, source_uuid);
 
 		listItem->setText(QT_UTF8(name.c_str()));
 		obs_source_set_name(source, name.c_str());
@@ -8482,7 +8481,7 @@ void undo_redo(const std::string &data)
 {
 	OBSDataAutoRelease dat = obs_data_create_from_json(data.c_str());
 	OBSSourceAutoRelease source =
-		obs_get_source_by_name(obs_data_get_string(dat, "scene_name"));
+		obs_get_source_by_uuid(obs_data_get_string(dat, "scene_uuid"));
 	reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 		->SetCurrentScene(source.Get(), true);
 
@@ -9948,8 +9947,8 @@ void OBSBasic::CreateFilterPasteUndoRedoAction(const QString &text,
 			obs_data_create_from_json(json.c_str());
 		OBSDataArrayAutoRelease array =
 			obs_data_get_array(data, "array");
-		const char *name = obs_data_get_string(data, "name");
-		OBSSourceAutoRelease source = obs_get_source_by_name(name);
+		OBSSourceAutoRelease source = obs_get_source_by_uuid(
+			obs_data_get_string(data, "uuid"));
 
 		obs_source_restore_filters(source, array);
 
@@ -9957,14 +9956,14 @@ void OBSBasic::CreateFilterPasteUndoRedoAction(const QString &text,
 			filters->UpdateSource(source);
 	};
 
-	const char *name = obs_source_get_name(source);
+	const char *uuid = obs_source_get_uuid(source);
 
 	OBSDataAutoRelease undo_data = obs_data_create();
 	OBSDataAutoRelease redo_data = obs_data_create();
 	obs_data_set_array(undo_data, "array", undo_array);
 	obs_data_set_array(redo_data, "array", redo_array);
-	obs_data_set_string(undo_data, "name", name);
-	obs_data_set_string(redo_data, "name", name);
+	obs_data_set_string(undo_data, "uuid", uuid);
+	obs_data_set_string(redo_data, "uuid", uuid);
 
 	undo_s.add_action(text, undo_redo, undo_redo,
 			  obs_data_get_json(undo_data),

+ 2 - 2
UI/window-basic-preview.cpp

@@ -794,8 +794,8 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
 	auto undo_redo = [](const std::string &data) {
 		OBSDataAutoRelease dat =
 			obs_data_create_from_json(data.c_str());
-		OBSSourceAutoRelease source = obs_get_source_by_name(
-			obs_data_get_string(dat, "scene_name"));
+		OBSSourceAutoRelease source = obs_get_source_by_uuid(
+			obs_data_get_string(dat, "scene_uuid"));
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			->SetCurrentScene(source.Get(), true);
 

+ 10 - 10
UI/window-basic-properties.cpp

@@ -317,20 +317,20 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
 
 	if (val == QDialogButtonBox::AcceptRole) {
 
-		std::string scene_name =
-			obs_source_get_name(main->GetCurrentSceneSource());
+		std::string scene_uuid =
+			obs_source_get_uuid(main->GetCurrentSceneSource());
 
-		auto undo_redo = [scene_name](const std::string &data) {
+		auto undo_redo = [scene_uuid](const std::string &data) {
 			OBSDataAutoRelease settings =
 				obs_data_create_from_json(data.c_str());
-			OBSSourceAutoRelease source = obs_get_source_by_name(
-				obs_data_get_string(settings, "undo_sname"));
+			OBSSourceAutoRelease source = obs_get_source_by_uuid(
+				obs_data_get_string(settings, "undo_uuid"));
 			obs_source_reset_settings(source, settings);
 
 			obs_source_update_properties(source);
 
 			OBSSourceAutoRelease scene_source =
-				obs_get_source_by_name(scene_name.c_str());
+				obs_get_source_by_uuid(scene_uuid.c_str());
 
 			OBSBasic::Get()->SetCurrentScene(scene_source.Get(),
 							 true);
@@ -340,10 +340,10 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button)
 		OBSDataAutoRelease curr_settings =
 			obs_source_get_settings(source);
 		obs_data_apply(new_settings, curr_settings);
-		obs_data_set_string(new_settings, "undo_sname",
-				    obs_source_get_name(source));
-		obs_data_set_string(oldSettings, "undo_sname",
-				    obs_source_get_name(source));
+		obs_data_set_string(new_settings, "undo_uuid",
+				    obs_source_get_uuid(source));
+		obs_data_set_string(oldSettings, "undo_uuid",
+				    obs_source_get_uuid(source));
 
 		std::string undo_data(obs_data_get_json(oldSettings));
 		std::string redo_data(obs_data_get_json(new_settings));

+ 2 - 2
UI/window-basic-transform.cpp

@@ -93,8 +93,8 @@ OBSBasicTransform::~OBSBasicTransform()
 	auto undo_redo = [](const std::string &data) {
 		OBSDataAutoRelease dat =
 			obs_data_create_from_json(data.c_str());
-		OBSSourceAutoRelease source = obs_get_source_by_name(
-			obs_data_get_string(dat, "scene_name"));
+		OBSSourceAutoRelease source = obs_get_source_by_uuid(
+			obs_data_get_string(dat, "scene_uuid"));
 		reinterpret_cast<OBSBasic *>(App()->GetMainWindow())
 			->SetCurrentScene(source.Get(), true);
 		obs_scene_load_transform_states(data.c_str());