Fix crash loading blend files with unknown space types
Logic which initialized a 3D viewport in ED_area_init only set it's type but didn't ensure `area->spacedata.first` pointed to a valid View3D. Resolve by adding or reusing the existing View3D. The check in `area_offscreen_init` has been replaced with an assert since the space_type for off-screen areas is set at run-time and should never be unknown.
This commit is contained in:
@@ -1925,6 +1925,39 @@ bool ED_area_has_shared_border(ScrArea *a, ScrArea *b)
|
||||
return area_getorientation(a, b) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a known space type in the event a file with an unknown space-type is loaded.
|
||||
*/
|
||||
static void area_init_type_fallback(ScrArea *area, eSpace_Type space_type)
|
||||
{
|
||||
BLI_assert(area->type == nullptr);
|
||||
area->spacetype = space_type;
|
||||
area->type = BKE_spacetype_from_id(area->spacetype);
|
||||
|
||||
SpaceLink *sl = nullptr;
|
||||
LISTBASE_FOREACH (SpaceLink *, sl_iter, &area->spacedata) {
|
||||
if (sl_iter->spacetype == space_type) {
|
||||
sl = sl_iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sl) {
|
||||
SpaceLink *sl_old = static_cast<SpaceLink *>(area->spacedata.first);
|
||||
if (LIKELY(sl != sl_old)) {
|
||||
BLI_remlink(&area->spacedata, sl);
|
||||
BLI_addhead(&area->spacedata, sl);
|
||||
|
||||
/* swap regions */
|
||||
sl_old->regionbase = area->regionbase;
|
||||
area->regionbase = sl->regionbase;
|
||||
BLI_listbase_clear(&sl->regionbase);
|
||||
}
|
||||
}
|
||||
else {
|
||||
screen_area_spacelink_add(nullptr, area, space_type);
|
||||
}
|
||||
}
|
||||
|
||||
void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
|
||||
{
|
||||
WorkSpace *workspace = WM_window_get_active_workspace(win);
|
||||
@@ -1943,8 +1976,8 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
|
||||
area->type = BKE_spacetype_from_id(area->spacetype);
|
||||
|
||||
if (area->type == nullptr) {
|
||||
area->spacetype = SPACE_VIEW3D;
|
||||
area->type = BKE_spacetype_from_id(area->spacetype);
|
||||
area_init_type_fallback(area, SPACE_VIEW3D);
|
||||
BLI_assert(area->type != nullptr);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
|
||||
@@ -2009,11 +2042,9 @@ static void area_offscreen_init(ScrArea *area)
|
||||
{
|
||||
area->flag |= AREA_FLAG_OFFSCREEN;
|
||||
area->type = BKE_spacetype_from_id(area->spacetype);
|
||||
|
||||
if (area->type == nullptr) {
|
||||
area->spacetype = SPACE_VIEW3D;
|
||||
area->type = BKE_spacetype_from_id(area->spacetype);
|
||||
}
|
||||
/* Off screen areas are only ever created at run-time,
|
||||
* so there is no reason for the type to be unknown. */
|
||||
BLI_assert(area->type != nullptr);
|
||||
|
||||
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
|
||||
region->type = BKE_regiontype_from_id_or_first(area->type, region->regiontype);
|
||||
|
||||
Reference in New Issue
Block a user