frontend: Fix handling scene remove signal from not main canvas#13150
frontend: Fix handling scene remove signal from not main canvas#13150exeldro wants to merge 1 commit intoobsproject:masterfrom
Conversation
|
I think |
ab1fc78 to
3cb838b
Compare
|
Moved the check to |
PatTheMav
left a comment
There was a problem hiding this comment.
The change itself looks correct, but I feel like we could use this opportunity to freshen up the implementation a bit:
void OBSBasic::RemoveScene(OBSSource source)
{
OBSCanvasAutoRelease canvas = obs_source_get_canvas(source);
if (!canvas) {
assert("OBSBasic::RemoveScene: Source passed to function has no associated canvas.");
return;
}
uint32_t canvasFlags = obs_canvas_get_flags(canvas);
bool isMainCanvas = (canvasFlags & MAIN);
bool isEphemeralCanvas = (canvasFlags & EPHEMERAL);
if (isMainCanvas) {
// Pointer lifetime coupled to strong reference to "source"
const char* sourceUuid = obs_source_get_uuid(source);
if (!sourceUuid) {
assert("OBSBasic::RemoveScene: Source passed to function has no UUID.");
return;
}
std::string_view lhs {sourceUuid};
SceneTree *scenes = ui->scenes;
auto findMatchingListItemRow = [](QListWidget *list, std::string_view uuid) -> std::optional<int> {
if (!list || uuid.empty()) {
return std::nullopt;
}
int numListItems = list->count();
for (int i = 0; i < numListItems; ++i) {
QListWidgetItem *item = list->item(i);
OBSScene sceneItem = GetOBSRef<OBSScene>(item);
OBSSource sourceItem = obs_scene_get_source(sceneItem);
const char *itemUuidPtr = obs_source_get_uuid(sourceItem);
if (!itemUuidPtr) {
continue;
}
std::string_view itemUuid {itemUuidPtr};
if (uuid != itemUuid) {
continue;
}
return {i};
}
return std::nullopt;
};
std::optional<int> match = findMatchingListItemRow(scenes, sourceUuid);
if (match) {
int matchedItemRow = match.value();
int currentItemRow = scenes->currentRow();
if (matchedItemRow == currentItemRow) {
ui->sources->Clear();
}
QListWidgetItem *matchedItem = scenes->takeItem(matchedItemRow);
delete matchedItem;
}
}
if (!isEphemeralCanvas) {
SaveProject();
}
if (isMainCanvas) {
if (!disableSaving) {
blog(LOG_INFO, "User Removed scene '%s'", obs_source_get_name(source));
OBSProjector::UpdateMultiviewProjectors();
}
OnEvent(OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED);
}
}@Warchamp7 please give this a whirl and check if I missed something. Scene identity is checked using the UUID and list item removal is based on the underlying data model index and not memory addresses.
|
Both of the above unfortunately run into the same problem I just dealt with on obs-websockets. The global We would have to connect to the canvas-specific source_remove signal for that, and that's out of scope here and a longer term fix. In the short term, I think we have to settle for simply checking if we removed something from the list. A scene from another canvas should never end up in the |
3cb838b to
6e9f0fe
Compare
|
Applied some of the changes suggested by @PatTheMav . As @Warchamp7 suggested now only trigger OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED when an item is removed from the scene list @Warchamp7 in what case can the global |
Websockets or a plugin |
Description
Fix handling scene remove signal from not main canvas
Motivation and Context
OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED was triggered when a scene on not main canvas was removed
How Has This Been Tested?
On windows 11 by removing a scene for an extra canvas.
Types of changes
Checklist: