2.5: fix for crashes due to access to free'd memory in joining areas,
ripping areas and duplicating windows.
This commit is contained in:
@@ -3649,16 +3649,25 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata)
|
||||
static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
|
||||
{
|
||||
uiMenuBlockHandle *menu= userdata;
|
||||
void (*popup_func)(struct bContext *C, void *arg, int event)= NULL;
|
||||
void *popup_arg= NULL;
|
||||
int retval= 0;
|
||||
|
||||
ui_handle_menus_recursive(C, event, menu);
|
||||
|
||||
/* free if done, does not free handle itself */
|
||||
if(menu->menuretval) {
|
||||
if(menu->menuretval == UI_RETURN_OK) {
|
||||
popup_func= menu->popup_func;
|
||||
popup_arg= menu->popup_arg;
|
||||
retval= menu->retvalue;
|
||||
}
|
||||
|
||||
ui_menu_block_free(C, menu);
|
||||
WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
|
||||
|
||||
if(menu->menuretval == UI_RETURN_OK && menu->popup_func)
|
||||
menu->popup_func(C, menu->popup_arg, menu->retvalue);
|
||||
if(popup_func)
|
||||
popup_func(C, popup_arg, retval);
|
||||
}
|
||||
else {
|
||||
/* re-enable tooltips */
|
||||
|
||||
@@ -264,7 +264,7 @@ static int screen_area_rip_op(bContext *C, wmOperator *op)
|
||||
|
||||
/* allocs new screen and adds to newly created window, using window size */
|
||||
newsc= screen_add(newwin, sc->id.name+2);
|
||||
win->screen= newsc;
|
||||
newwin->screen= newsc;
|
||||
|
||||
/* copy area to new screen */
|
||||
area_copy_data((ScrArea *)newsc->areabase.first, sa, 0);
|
||||
@@ -767,6 +767,7 @@ static int area_split_cancel(bContext *C, wmOperator *op)
|
||||
if (screen_area_join(C, CTX_wm_screen(C), sd->sarea, sd->narea)) {
|
||||
if (CTX_wm_area(C) == sd->narea) {
|
||||
CTX_wm_area_set(C, NULL);
|
||||
CTX_wm_region_set(C, NULL);
|
||||
}
|
||||
sd->narea = NULL;
|
||||
}
|
||||
@@ -1018,6 +1019,7 @@ static int area_join_apply(bContext *C, wmOperator *op)
|
||||
}
|
||||
if (CTX_wm_area(C) == jd->sa2) {
|
||||
CTX_wm_area_set(C, NULL);
|
||||
CTX_wm_region_set(C, NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -441,6 +441,12 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int wm_event_always_pass(wmEvent *event)
|
||||
{
|
||||
/* some events we always pass on, to ensure proper communication */
|
||||
return (event->type == TIMER);
|
||||
}
|
||||
|
||||
/* Warning: this function removes a modal handler, when finished */
|
||||
static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event, IDProperty *properties)
|
||||
{
|
||||
@@ -462,8 +468,15 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
|
||||
retval= ot->modal(C, op, event);
|
||||
|
||||
/* putting back screen context */
|
||||
CTX_wm_area_set(C, area);
|
||||
CTX_wm_region_set(C, region);
|
||||
if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
|
||||
CTX_wm_area_set(C, area);
|
||||
CTX_wm_region_set(C, region);
|
||||
}
|
||||
else {
|
||||
/* this special cases is for areas and regions that get removed */
|
||||
CTX_wm_area_set(C, NULL);
|
||||
CTX_wm_region_set(C, NULL);
|
||||
}
|
||||
|
||||
if((retval & OPERATOR_FINISHED) && (ot->flag & OPTYPE_REGISTER)) {
|
||||
wm_operator_register(CTX_wm_manager(C), op);
|
||||
@@ -474,7 +487,6 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
|
||||
handler->op= NULL;
|
||||
}
|
||||
|
||||
|
||||
/* remove modal handler, operator itself should have been cancelled and freed */
|
||||
if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
|
||||
BLI_remlink(handlers, handler);
|
||||
@@ -524,12 +536,6 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
|
||||
return WM_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static int wm_event_always_pass(wmEvent *event)
|
||||
{
|
||||
/* some events we always pass on, to ensure proper communication */
|
||||
return (event->type == TIMER);
|
||||
}
|
||||
|
||||
static int handler_boundbox_test(wmEventHandler *handler, wmEvent *event)
|
||||
{
|
||||
if(handler->bbwin) {
|
||||
|
||||
Reference in New Issue
Block a user