[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