Proper fix for crash when joining areas that doesn't break manipulators
Turns out CTX_wm_region returns mostly NULL in wm_manipulatormaps_handled_modal_update. Now propertly unsetting area/region data of handlers when deleting area/region.
This commit is contained in:
parent
e7fddc0772
commit
4811b2d356
Notes:
blender-bot
2023-02-14 10:35:28 +01:00
Referenced by commit 82ba89b042
, Fix T49961: Blender 2.8 Crashes on saving an image
|
@ -1277,25 +1277,28 @@ void ED_screens_initialize(wmWindowManager *wm)
|
|||
void ED_region_exit(bContext *C, ARegion *ar)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ARegion *prevar = CTX_wm_region(C);
|
||||
|
||||
if (ar->type && ar->type->exit)
|
||||
ar->type->exit(wm, ar);
|
||||
|
||||
CTX_wm_region_set(C, ar);
|
||||
|
||||
WM_event_remove_handlers(C, &ar->handlers);
|
||||
WM_event_modal_handler_region_replace(win, ar, NULL);
|
||||
if (ar->swinid) {
|
||||
wm_subwindow_close(CTX_wm_window(C), ar->swinid);
|
||||
wm_subwindow_close(win, ar->swinid);
|
||||
ar->swinid = 0;
|
||||
}
|
||||
|
||||
|
||||
if (ar->headerstr) {
|
||||
MEM_freeN(ar->headerstr);
|
||||
ar->headerstr = NULL;
|
||||
}
|
||||
|
||||
if (ar->regiontimer) {
|
||||
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer);
|
||||
WM_event_remove_timer(wm, win, ar->regiontimer);
|
||||
ar->regiontimer = NULL;
|
||||
}
|
||||
|
||||
|
@ -1305,6 +1308,7 @@ void ED_region_exit(bContext *C, ARegion *ar)
|
|||
void ED_area_exit(bContext *C, ScrArea *sa)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ScrArea *prevsa = CTX_wm_area(C);
|
||||
ARegion *ar;
|
||||
|
||||
|
@ -1312,10 +1316,13 @@ void ED_area_exit(bContext *C, ScrArea *sa)
|
|||
sa->type->exit(wm, sa);
|
||||
|
||||
CTX_wm_area_set(C, sa);
|
||||
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next)
|
||||
ED_region_exit(C, ar);
|
||||
|
||||
WM_event_remove_handlers(C, &sa->handlers);
|
||||
WM_event_modal_handler_area_replace(win, sa, NULL);
|
||||
|
||||
CTX_wm_area_set(C, prevsa);
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ struct wmDrag;
|
|||
struct ImBuf;
|
||||
struct ImageFormatData;
|
||||
struct ARegion;
|
||||
struct ScrArea;
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
struct wmNDOFMotionData;
|
||||
|
@ -177,6 +178,9 @@ void WM_event_free_ui_handler_all(
|
|||
wmUIHandlerFunc ui_handle, wmUIHandlerRemoveFunc ui_remove);
|
||||
|
||||
struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
|
||||
void WM_event_modal_handler_area_replace(wmWindow *win, const struct ScrArea *old_area, struct ScrArea *new_area);
|
||||
void WM_event_modal_handler_region_replace(wmWindow *win, const struct ARegion *old_region, struct ARegion *new_region);
|
||||
|
||||
void WM_event_remove_handlers(struct bContext *C, ListBase *handlers);
|
||||
|
||||
/* handler flag */
|
||||
|
|
|
@ -2717,6 +2717,33 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
|
|||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modal handlers store a pointer to an area which might be freed while the handler runs.
|
||||
* Use this function to NULL all handler pointers to \a old_area.
|
||||
*/
|
||||
void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area)
|
||||
{
|
||||
for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
|
||||
if (handler->op_area == old_area) {
|
||||
handler->op_area = new_area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modal handlers store a pointer to a region which might be freed while the handler runs.
|
||||
* Use this function to NULL all handler pointers to \a old_region.
|
||||
*/
|
||||
void WM_event_modal_handler_region_replace(wmWindow *win, const ARegion *old_region, ARegion *new_region)
|
||||
{
|
||||
for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
|
||||
if (handler->op_region == old_region) {
|
||||
handler->op_region = new_region;
|
||||
handler->op_region_type = new_region ? new_region->regiontype : RGN_TYPE_WINDOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
|
||||
{
|
||||
wmEventHandler *handler;
|
||||
|
|
|
@ -394,12 +394,10 @@ void wm_manipulatormaps_handled_modal_update(
|
|||
bContext *C, wmEvent *event, wmEventHandler *handler,
|
||||
const wmOperatorType *ot)
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
const bool modal_running = (handler->op != NULL);
|
||||
|
||||
/* happens on render or when joining areas */
|
||||
if (!region || !region->manipulator_map)
|
||||
if (!handler->op_region || !handler->op_region->manipulator_map)
|
||||
return;
|
||||
|
||||
/* hide operator manipulators */
|
||||
|
@ -407,8 +405,10 @@ void wm_manipulatormaps_handled_modal_update(
|
|||
ot->mgrouptype->op = NULL;
|
||||
}
|
||||
|
||||
wmManipulatorMap *mmap = region->manipulator_map;
|
||||
wmManipulatorMap *mmap = handler->op_region->manipulator_map;
|
||||
wmManipulator *manipulator = wm_manipulatormap_get_active_manipulator(mmap);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
|
||||
wm_manipulatormap_handler_context(C, handler);
|
||||
|
||||
|
|
Loading…
Reference in New Issue