[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37589] trunk/blender/source/blender: fix [#26621] Memory leaks when creating popup window.
Campbell Barton
ideasman42 at gmail.com
Fri Jun 17 14:48:34 CEST 2011
Revision: 37589
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37589
Author: campbellbarton
Date: 2011-06-17 12:48:33 +0000 (Fri, 17 Jun 2011)
Log Message:
-----------
fix [#26621] Memory leaks when creating popup window.
also fixes memory leak when cancelling a popup dialog (new image for example).
Modified Paths:
--------------
trunk/blender/source/blender/editors/include/UI_interface.h
trunk/blender/source/blender/editors/interface/interface_regions.c
trunk/blender/source/blender/windowmanager/intern/wm_operators.c
Modified: trunk/blender/source/blender/editors/include/UI_interface.h
===================================================================
--- trunk/blender/source/blender/editors/include/UI_interface.h 2011-06-17 11:47:45 UTC (rev 37588)
+++ trunk/blender/source/blender/editors/include/UI_interface.h 2011-06-17 12:48:33 UTC (rev 37589)
@@ -298,10 +298,12 @@
* 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);
Modified: trunk/blender/source/blender/editors/interface/interface_regions.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_regions.c 2011-06-17 11:47:45 UTC (rev 37588)
+++ trunk/blender/source/blender/editors/interface/interface_regions.c 2011-06-17 12:48:33 UTC (rev 37589)
@@ -2582,6 +2582,25 @@
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 @@
UI_add_popup_handlers(C, &window->modalhandlers, handle);
WM_event_add_mousemove(C);
}
+#endif
void uiPupBlockClose(bContext *C, uiBlock *block)
{
Modified: trunk/blender/source/blender/windowmanager/intern/wm_operators.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_operators.c 2011-06-17 11:47:45 UTC (rev 37588)
+++ trunk/blender/source/blender/windowmanager/intern/wm_operators.c 2011-06-17 12:48:33 UTC (rev 37589)
@@ -938,14 +938,29 @@
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 @@
}
/* 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 @@
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 @@
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 @@
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_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 */
More information about the Bf-blender-cvs
mailing list