diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-10-31 17:43:30 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-10-31 17:43:30 +0300 |
commit | 184b5fd6db4dfedb5c436ca1021bbe52df289a32 (patch) | |
tree | 469c0882950c2148086907de5ab92eca51ce3fcb /source/blender/windowmanager | |
parent | 391c547208184e80d1d16acb792574d9f5b63d10 (diff) |
bugfix [#24466] Selecting of object with pattern leads to strange behavior
The undo problem was caused by python operators returning 'RUNNING_MODAL' rather then the return value from wm.invoke_props_popup(self, event) - 'FINISHED'.
This was done because returning FINISHED would free the operator causing the buttons redo handler to try and run a freed operator and crash.
So the real fix is to disallow any operators to use wm.invoke_props_popup(self, event) if they dont have the REGISTER option enabled, fixing the crash and redo problem.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 16 |
2 files changed, 18 insertions, 2 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 47ca4314cc7..4eba45c61b9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -364,9 +364,9 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot) wmOperatorTypeMacro *otmacro; for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) { - wmOperatorType *ot= WM_operatortype_find(otmacro->idname, 0); + wmOperatorType *ot_macro= WM_operatortype_find(otmacro->idname, 0); - if(0==WM_operator_poll(C, ot)) + if(0==WM_operator_poll(C, ot_macro)) return 0; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ccdb19adfce..2a9ef1e752e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -31,6 +31,7 @@ #include <ctype.h> #include <stdio.h> #include <stddef.h> +#include <assert.h> #ifdef WIN32 #include <windows.h> #include <io.h> @@ -889,6 +890,11 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); + + /* if register is not enabled, the operator gets freed on OPERATOR_FINISHED + * ui_apply_but_funcs_after calls redo_cb and crashes */ + assert(op->type->flag & OPTYPE_REGISTER); + uiBlockSetHandleFunc(block, redo_cb, arg_op); if(!op->properties) { @@ -1021,6 +1027,11 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { int retval= OPERATOR_CANCELLED; + if((op->type->flag & OPTYPE_REGISTER)==0) { + BKE_reportf(op->reports, RPT_ERROR, "Operator '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + return OPERATOR_CANCELLED; + } + if(op->type->exec) { retval= op->type->exec(C, op); @@ -1059,6 +1070,11 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) int WM_operator_redo_popup(bContext *C, wmOperator *op) { + if((op->type->flag & OPTYPE_REGISTER)==0) { + BKE_reportf(op->reports, RPT_ERROR, "Operator '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + return OPERATOR_CANCELLED; + } + uiPupBlock(C, wm_block_create_redo, op); return OPERATOR_CANCELLED; |