fix [#26621] Memory leaks when creating popup window.
also fixes memory leak when cancelling a popup dialog (new image for example).
This commit is contained in:
parent
46ef1bb170
commit
68a12c74b6
@ -298,10 +298,12 @@ void uiPupMenuInvoke(struct bContext *C, const char *idname); /* popup registere
|
||||
* but allow using all button types and creating an own layout. */
|
||||
|
||||
typedef uiBlock* (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
|
||||
typedef void (*uiBlockCancelFunc)(void *arg1);
|
||||
|
||||
void uiPupBlock(struct bContext *C, uiBlockCreateFunc func, void *arg);
|
||||
void uiPupBlockO(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
|
||||
void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext);
|
||||
void uiPupBlockEx(struct bContext *C, uiBlockCreateFunc func, uiBlockCancelFunc cancel_func, void *arg);
|
||||
/* void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext); */ /* UNUSED */
|
||||
|
||||
void uiPupBlockClose(struct bContext *C, uiBlock *block);
|
||||
|
||||
|
@ -2582,6 +2582,25 @@ void uiPupBlock(bContext *C, uiBlockCreateFunc func, void *arg)
|
||||
uiPupBlockO(C, func, arg, NULL, 0);
|
||||
}
|
||||
|
||||
void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockCancelFunc cancel_func, void *arg)
|
||||
{
|
||||
wmWindow *window= CTX_wm_window(C);
|
||||
uiPopupBlockHandle *handle;
|
||||
|
||||
handle= ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
|
||||
handle->popup= 1;
|
||||
handle->retvalue= 1;
|
||||
|
||||
handle->popup_arg= arg;
|
||||
// handle->popup_func= operator_cb;
|
||||
handle->cancel_func= cancel_func;
|
||||
// handle->opcontext= opcontext;
|
||||
|
||||
UI_add_popup_handlers(C, &window->modalhandlers, handle);
|
||||
WM_event_add_mousemove(C);
|
||||
}
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int opcontext)
|
||||
{
|
||||
wmWindow *window= CTX_wm_window(C);
|
||||
@ -2599,6 +2618,7 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int
|
||||
UI_add_popup_handlers(C, &window->modalhandlers, handle);
|
||||
WM_event_add_mousemove(C);
|
||||
}
|
||||
#endif
|
||||
|
||||
void uiPupBlockClose(bContext *C, uiBlock *block)
|
||||
{
|
||||
|
@ -938,13 +938,28 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
|
||||
return block;
|
||||
}
|
||||
|
||||
/* Only invoked by OK button in popups created with wm_block_create_dialog() */
|
||||
typedef struct wmOpPopUp
|
||||
{
|
||||
wmOperator *op;
|
||||
int width;
|
||||
int height;
|
||||
int free_op;
|
||||
} wmOpPopUp;
|
||||
|
||||
/* Only invoked by OK button in popups created with wm_block_dialog_create() */
|
||||
static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
|
||||
{
|
||||
wmOperator *op= arg1;
|
||||
wmOpPopUp *data= arg1;
|
||||
uiBlock *block= arg2;
|
||||
|
||||
WM_operator_call(C, op);
|
||||
WM_operator_call(C, data->op);
|
||||
|
||||
/* let execute handle freeing it */
|
||||
//data->free_op= FALSE;
|
||||
//data->op= NULL;
|
||||
|
||||
/* in this case, wm_operator_ui_popup_cancel wont run */
|
||||
MEM_freeN(data);
|
||||
|
||||
uiPupBlockClose(C, block);
|
||||
}
|
||||
@ -960,9 +975,9 @@ static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
|
||||
}
|
||||
|
||||
/* Dialogs are popups that require user verification (click OK) before exec */
|
||||
static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
|
||||
static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
|
||||
{
|
||||
struct { wmOperator *op; int width; int height; } * data = userData;
|
||||
wmOpPopUp *data= userData;
|
||||
wmOperator *op= data->op;
|
||||
uiBlock *block;
|
||||
uiLayout *layout;
|
||||
@ -991,7 +1006,7 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
|
||||
col_block= uiLayoutGetBlock(col);
|
||||
/* Create OK button, the callback of which will execute op */
|
||||
btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||
uiButSetFunc(btn, dialog_exec_cb, op, col_block);
|
||||
uiButSetFunc(btn, dialog_exec_cb, data, col_block);
|
||||
}
|
||||
|
||||
/* center around the mouse */
|
||||
@ -1001,9 +1016,9 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
|
||||
return block;
|
||||
}
|
||||
|
||||
static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
|
||||
static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
|
||||
{
|
||||
struct { wmOperator *op; int width; int height; } * data = userData;
|
||||
wmOpPopUp *data= userData;
|
||||
wmOperator *op= data->op;
|
||||
uiBlock *block;
|
||||
uiLayout *layout;
|
||||
@ -1024,6 +1039,28 @@ static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
|
||||
return block;
|
||||
}
|
||||
|
||||
static void wm_operator_ui_popup_cancel(void *userData)
|
||||
{
|
||||
wmOpPopUp *data= userData;
|
||||
if(data->free_op && data->op) {
|
||||
wmOperator *op= data->op;
|
||||
WM_operator_free(op);
|
||||
}
|
||||
|
||||
MEM_freeN(data);
|
||||
}
|
||||
|
||||
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
|
||||
{
|
||||
wmOpPopUp *data= MEM_callocN(sizeof(wmOpPopUp), "WM_operator_ui_popup");
|
||||
data->op= op;
|
||||
data->width= width;
|
||||
data->height= height;
|
||||
data->free_op= TRUE; /* if this runs and gets registered we may want not to free it */
|
||||
uiPupBlockEx(C, wm_operator_ui_create, wm_operator_ui_popup_cancel, data);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
/* operator menu needs undo, for redo callback */
|
||||
int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
||||
{
|
||||
@ -1043,28 +1080,19 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
||||
|
||||
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
|
||||
{
|
||||
struct { wmOperator *op; int width; int height; } data;
|
||||
wmOpPopUp *data= MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup");
|
||||
|
||||
data.op= op;
|
||||
data.width= width;
|
||||
data.height= height;
|
||||
data->op= op;
|
||||
data->width= width;
|
||||
data->height= height;
|
||||
data->free_op= TRUE; /* if this runs and gets registered we may want not to free it */
|
||||
|
||||
/* op is not executed until popup OK but is clicked */
|
||||
uiPupBlock(C, wm_block_create_dialog, &data);
|
||||
uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_cancel, data);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
|
||||
{
|
||||
struct { wmOperator *op; int width; int height; } data;
|
||||
data.op = op;
|
||||
data.width = width;
|
||||
data.height = height;
|
||||
uiPupBlock(C, wm_operator_create_ui, &data);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
int WM_operator_redo_popup(bContext *C, wmOperator *op)
|
||||
{
|
||||
/* CTX_wm_reports(C) because operator is on stack, not active in event system */
|
||||
|
Loading…
Reference in New Issue
Block a user