libobs: When ungrouping groups, duplicate items
Because groups can now be used in multiple scenes at once, it's important that if the user wishes to ungroup a group, that they must be able to keep the group intact if it exists in other scenes. This requires duplicating all scene items (as well as their hotkey/private data) instead of just reparenting the subitems. This fixes an issue where if the user had the group referenced in multiple scenes, the group would become empty in other scenes.
This commit is contained in:
@@ -32,6 +32,8 @@ static void get_ungrouped_transform(obs_sceneitem_t *group,
|
||||
float *rot);
|
||||
static inline bool crop_enabled(const struct obs_sceneitem_crop *crop);
|
||||
static inline bool item_texture_enabled(const struct obs_scene_item *item);
|
||||
static void init_hotkeys(obs_scene_t *scene, obs_sceneitem_t *item,
|
||||
const char *name);
|
||||
|
||||
/* NOTE: For proper mutex lock order (preventing mutual cross-locks), never
|
||||
* lock the graphics mutex inside either of the scene mutexes.
|
||||
@@ -2565,49 +2567,38 @@ void obs_sceneitem_group_ungroup(obs_sceneitem_t *item)
|
||||
|
||||
obs_scene_t *scene = item->parent;
|
||||
obs_scene_t *subscene = item->source->context.data;
|
||||
obs_sceneitem_t *insert_after = item;
|
||||
obs_sceneitem_t *first;
|
||||
obs_sceneitem_t *last;
|
||||
|
||||
full_lock(scene);
|
||||
|
||||
/* ------------------------- */
|
||||
|
||||
full_lock(subscene);
|
||||
first = subscene->first_item;
|
||||
last = first;
|
||||
while (last) {
|
||||
obs_sceneitem_t *dst;
|
||||
|
||||
remove_group_transform(item, last);
|
||||
last->parent = scene;
|
||||
dst = obs_scene_add_internal(scene, last->source, insert_after);
|
||||
duplicate_item_data(dst, last, true, true, true);
|
||||
apply_group_transform(last, item);
|
||||
|
||||
if (!last->next)
|
||||
break;
|
||||
|
||||
insert_after = dst;
|
||||
last = last->next;
|
||||
}
|
||||
subscene->first_item = NULL;
|
||||
subscene->cx = 0;
|
||||
subscene->cy = 0;
|
||||
full_unlock(subscene);
|
||||
|
||||
/* ------------------------- */
|
||||
|
||||
full_lock(scene);
|
||||
if (last) {
|
||||
if (item->prev) {
|
||||
first->prev = item->prev;
|
||||
item->prev->next = first;
|
||||
} else {
|
||||
scene->first_item = first;
|
||||
first->prev = NULL;
|
||||
}
|
||||
last->next = item->next;
|
||||
if (last->next)
|
||||
last->next->prev = last;
|
||||
item->next = item->prev = NULL;
|
||||
item->parent = NULL;
|
||||
} else {
|
||||
detach_sceneitem(item);
|
||||
}
|
||||
detach_sceneitem(item);
|
||||
full_unlock(scene);
|
||||
|
||||
/* ------------------------- */
|
||||
|
||||
obs_sceneitem_release(item);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user