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:
committed by
Julian Eisel
parent
9380e2d5d8
commit
172e9c5b83
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user