Commit: 4811b2d3565cf72a08d8bc55d1717e71d18f7df1 Author: Julian Eisel Date: Mon Oct 17 19:25:56 2016 +0200 Branches: blender2.8 https://developer.blender.org/rB4811b2d3565cf72a08d8bc55d1717e71d18f7df1
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. =================================================================== M source/blender/editors/screen/screen_edit.c M source/blender/windowmanager/WM_api.h M source/blender/windowmanager/intern/wm_event_system.c M source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c =================================================================== diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 3d30f2b..5e00d15 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -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); } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 4d159c6..2809795 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -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 */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index a75b3b1..b15b47c 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -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; diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c index eada6e3..500092f 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c @@ -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); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs