Fix #130583: Crash opening a file when asset shelf is set for non-paint modes

The region type isn't set yet when polling regions just after file read. As a
result, the polling state cannot be evaluated correctly, and `init()` may end
up being called without the previous required call to `on_poll_success()`.

Ensure the region type is set earlier, right at the beginning of screen
initialization after file read. This way all further area/region
referesh/re-init (confusingly called "init") logic can assume it's set.

Pull Request: https://projects.blender.org/blender/blender/pulls/131050
This commit is contained in:
Julian Eisel
2024-12-03 16:57:38 +01:00
committed by Julian Eisel
parent 9380e2d5d8
commit 172e9c5b83
3 changed files with 35 additions and 15 deletions

View File

@@ -207,6 +207,10 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf);
int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco);
/* areas */
/**
* Ensure #ScrArea.type and #ARegion.type are set and valid.
*/
void ED_area_and_region_types_init(ScrArea *area);
/**
* Called in screen_refresh, or screens_init, also area size changes.
*/

View File

@@ -2027,6 +2027,23 @@ static void area_init_type_fallback(ScrArea *area, eSpace_Type space_type)
}
}
void ED_area_and_region_types_init(ScrArea *area)
{
area->type = BKE_spacetype_from_id(area->spacetype);
if (area->type == nullptr) {
area_init_type_fallback(area, SPACE_VIEW3D);
BLI_assert(area->type != nullptr);
}
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region->runtime->type = BKE_regiontype_from_id(area->type, region->regiontype);
/* Invalid region types may be stored in files (e.g. for new files), but they should be handled
* on file read already, see #BKE_screen_area_blend_read_lib(). */
BLI_assert_msg(region->runtime->type != nullptr, "Region type not valid for this space type");
}
}
void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
WorkSpace *workspace = WM_window_get_active_workspace(win);
@@ -2041,20 +2058,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
rcti window_rect;
WM_window_rect_calc(win, &window_rect);
/* Set type-definitions. */
area->type = BKE_spacetype_from_id(area->spacetype);
if (area->type == nullptr) {
area_init_type_fallback(area, SPACE_VIEW3D);
BLI_assert(area->type != nullptr);
}
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region->runtime->type = BKE_regiontype_from_id(area->type, region->regiontype);
/* Invalid region types may be stored in files (e.g. for new files), but they should be handled
* on file read already, see #BKE_screen_area_blend_read_lib(). */
BLI_assert_msg(region->runtime->type != nullptr, "Region type not valid for this space type");
}
ED_area_and_region_types_init(area);
/* area sizes */
area_calc_totrct(area, &window_rect);

View File

@@ -673,7 +673,11 @@ static bool region_poll(const bContext *C,
const ScrArea *area,
const ARegion *region)
{
if (!region->runtime->type || !region->runtime->type->poll) {
if (!region->runtime->type) {
BLI_assert_unreachable();
return false;
}
if (!region->runtime->type->poll) {
/* Show region by default. */
return true;
}
@@ -801,6 +805,14 @@ void ED_screens_init(bContext *C, Main *bmain, wmWindowManager *wm)
static_cast<WorkSpace *>(bmain->workspaces.first));
}
const bScreen *screen = WM_window_get_active_screen(win);
ED_screen_areas_iter (win, screen, area) {
/* Set area and region types early so areas and regions are in a usable state. This may be
* needed by further (re-)initialization logic, specifically region polling needs it early on
* (see #130583). */
ED_area_and_region_types_init(area);
}
ED_screen_refresh(C, wm, win);
if (win->eventstate) {
ED_screen_set_active_region(nullptr, win, win->eventstate->xy);