[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31577] trunk/blender/source/blender/ editors/interface: Fix #23433: crash with undo where a UI button was still active and accessing

Brecht Van Lommel brecht at blender.org
Wed Aug 25 11:33:49 CEST 2010


Revision: 31577
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31577
Author:   blendix
Date:     2010-08-25 11:33:48 +0200 (Wed, 25 Aug 2010)

Log Message:
-----------
Fix #23433: crash with undo where a UI button was still active and accessing
data that was freed.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/interface.c
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_intern.h

Modified: trunk/blender/source/blender/editors/interface/interface.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface.c	2010-08-25 09:30:52 UTC (rev 31576)
+++ trunk/blender/source/blender/editors/interface/interface.c	2010-08-25 09:33:48 UTC (rev 31577)
@@ -1765,9 +1765,11 @@
 	}
 	if(but->func_argN) MEM_freeN(but->func_argN);
 	if(but->active) {
-		/* XXX solve later, buttons should be free-able without context? */
+		/* XXX solve later, buttons should be free-able without context ideally,
+		   however they may have open tooltips or popup windows, which need to
+		   be closed using a context pointer */
 		if(C) 
-			ui_button_active_cancel(C, but);
+			ui_button_active_free(C, but);
 		else
 			if(but->active) 
 				MEM_freeN(but->active);

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2010-08-25 09:30:52 UTC (rev 31576)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2010-08-25 09:33:48 UTC (rev 31577)
@@ -4777,7 +4777,7 @@
 		button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
 }
 
-static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *but, int mousemove)
+static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *but, int mousemove, int onfree)
 {
 	uiBlock *block= but->block;
 	uiBut *bt;
@@ -4787,7 +4787,8 @@
 		button_activate_state(C, but, BUTTON_STATE_EXIT);
 
 	/* apply the button action or value */
-	ui_apply_button(C, block, but, data, 0);
+	if(!onfree)
+		ui_apply_button(C, block, but, data, 0);
 
 	/* if this button is in a menu, this will set the button return
 	 * value to the button value and the menu return value to ok, the
@@ -4802,7 +4803,7 @@
 		}
 	}
 
-	if(!data->cancel) {
+	if(!onfree && !data->cancel) {
 		/* autokey & undo push */
 		ui_apply_autokey_undo(C, but);
 
@@ -4835,7 +4836,8 @@
 	but->active= NULL;
 	but->flag &= ~(UI_ACTIVE|UI_SELECT);
 	but->flag |= UI_BUT_LAST_ACTIVE;
-	ui_check_but(but);
+	if(!onfree)
+		ui_check_but(but);
 
 	/* adds empty mousemove in queue for re-init handler, in case mouse is
 	 * still over a button. we cannot just check for this ourselfs because
@@ -4844,7 +4846,7 @@
 		WM_event_add_mousemove(C);
 }
 
-void ui_button_active_cancel(const bContext *C, uiBut *but)
+void ui_button_active_free(const bContext *C, uiBut *but)
 {
 	uiHandleButtonData *data;
 
@@ -4854,7 +4856,7 @@
 	if(but->active) {
 		data= but->active;
 		data->cancel= 1;
-		button_activate_exit((bContext*)C, data, but, 0);
+		button_activate_exit((bContext*)C, data, but, 0, 1);
 	}
 }
 
@@ -4920,7 +4922,7 @@
 	if(oldbut) {
 		data= oldbut->active;
 		data->cancel= 1;
-		button_activate_exit(C, data, oldbut, 0);
+		button_activate_exit(C, data, oldbut, 0, 0);
 	}
 
 	button_activate_init(C, ar, but, type);
@@ -5078,7 +5080,7 @@
 		postbut= data->postbut;
 		posttype= data->posttype;
 
-		button_activate_exit(C, data, but, (postbut == NULL));
+		button_activate_exit(C, data, but, (postbut == NULL), 0);
 
 		/* for jumping to the next button with tab while text editing */
 		if(postbut)
@@ -5182,7 +5184,7 @@
 		if(menu->menuretval != UI_RETURN_OK)
 			data->cancel= 1;
 
-		button_activate_exit(C, data, but, 1);
+		button_activate_exit(C, data, but, 1, 0);
 	}
 	else if(menu->menuretval == UI_RETURN_OUT) {
 		if(event->type==MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) {
@@ -5196,7 +5198,7 @@
 			}
 			else {
 				data->cancel= 1;
-				button_activate_exit(C, data, but, 1);
+				button_activate_exit(C, data, but, 1, 0);
 			}
 		}
 	}

Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h	2010-08-25 09:30:52 UTC (rev 31576)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h	2010-08-25 09:33:48 UTC (rev 31577)
@@ -456,7 +456,7 @@
 
 /* interface_handlers.c */
 extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
-extern void ui_button_active_cancel(const struct bContext *C, uiBut *but);
+extern void ui_button_active_free(const struct bContext *C, uiBut *but);
 extern int ui_button_is_active(struct ARegion *ar);
 
 /* interface_widgets.c */





More information about the Bf-blender-cvs mailing list