[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36242] trunk/blender/source/blender: Bugfix #27058

Ton Roosendaal ton at blender.org
Wed Apr 20 13:15:58 CEST 2011


Revision: 36242
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36242
Author:   ton
Date:     2011-04-20 11:15:58 +0000 (Wed, 20 Apr 2011)
Log Message:
-----------
Bugfix #27058

Top bar: Add -> Mesh -> UV Sphere + Enter crashed.
It didn't crash with leftmouse, but that was coincidentally working.

Menus were freeing modal handlers in Window, while handlers were still 
in use. Fix provides to tag handlers for being freed now.

Will add on my attention list for more elaborate checking work here, for
upcoming 2.57a I rather stick to minimal change in code here.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_panel.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/blender/windowmanager/wm_event_system.h

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2011-04-20 10:50:56 UTC (rev 36241)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2011-04-20 11:15:58 UTC (rev 36242)
@@ -4898,7 +4898,7 @@
 		}
 		else {
 			if(button_modal_state(data->state))
-				WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data);
+				WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, 1); /* 1 = postpone free */
 		}
 	}
 	
@@ -6154,7 +6154,7 @@
 
 void UI_add_region_handlers(ListBase *handlers)
 {
-	WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL);
+	WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, 0);
 	WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL);
 }
 
@@ -6165,7 +6165,7 @@
 
 void UI_remove_popup_handlers(ListBase *handlers, uiPopupBlockHandle *popup)
 {
-	WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup);
+	WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, 0);
 }
 
 

Modified: trunk/blender/source/blender/editors/interface/interface_panel.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_panel.c	2011-04-20 10:50:56 UTC (rev 36241)
+++ trunk/blender/source/blender/editors/interface/interface_panel.c	2011-04-20 11:15:58 UTC (rev 36242)
@@ -1211,7 +1211,7 @@
 		MEM_freeN(data);
 		pa->activedata= NULL;
 
-		WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa);
+		WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0);
 	}
 	else {
 		if(!data) {

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h	2011-04-20 10:50:56 UTC (rev 36241)
+++ trunk/blender/source/blender/windowmanager/WM_api.h	2011-04-20 11:15:58 UTC (rev 36242)
@@ -173,7 +173,7 @@
 			void (*remove)(struct bContext *C, void *userdata), void *userdata);
 void		WM_event_remove_ui_handler(ListBase *handlers,
 			int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
-			void (*remove)(struct bContext *C, void *userdata), void *userdata);
+			void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone);
 void		WM_event_remove_area_handler(struct ListBase *handlers, void *area);
 
 struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2011-04-20 10:50:56 UTC (rev 36241)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2011-04-20 11:15:58 UTC (rev 36242)
@@ -1452,10 +1452,13 @@
 
 	/* modal handlers can get removed in this loop, we keep the loop this way */
 	for(handler= handlers->first; handler; handler= nexthandler) {
+		
 		nexthandler= handler->next;
-
-		/* optional boundbox */
-		if(handler_boundbox_test(handler, event)) {
+		
+		/* during this loop, ui handlers for nested menus can tag multiple handlers free */
+		if(handler->flag & WM_HANDLER_DO_FREE);
+			/* optional boundbox */
+		else if(handler_boundbox_test(handler, event)) {
 			/* in advance to avoid access to freed event on window close */
 			always_pass= wm_event_always_pass(event);
 		
@@ -1534,6 +1537,13 @@
 			}
 		}
 		
+		/* modal ui handler can be tagged to be freed */ 
+		if(handler->flag & WM_HANDLER_DO_FREE) {
+			BLI_remlink(handlers, handler);
+			wm_event_free_handler(handler);
+		}
+
+		
 		/* XXX fileread case */
 		if(CTX_wm_window(C)==NULL)
 			return action;
@@ -2067,14 +2077,21 @@
 	return handler;
 }
 
-void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata)
+/* set "postpone" for win->modalhandlers, this is in a running for() loop in wm_handlers_do() */
+void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata, int postpone)
 {
 	wmEventHandler *handler;
 	
 	for(handler= handlers->first; handler; handler= handler->next) {
 		if(handler->ui_handle == func && handler->ui_remove == remove && handler->ui_userdata == userdata) {
-			BLI_remlink(handlers, handler);
-			wm_event_free_handler(handler);
+			/* handlers will be freed in wm_handlers_do() */
+			if(postpone) {
+				handler->flag |= WM_HANDLER_DO_FREE;
+			}
+			else {
+				BLI_remlink(handlers, handler);
+				wm_event_free_handler(handler);
+			}
 			break;
 		}
 	}

Modified: trunk/blender/source/blender/windowmanager/wm_event_system.h
===================================================================
--- trunk/blender/source/blender/windowmanager/wm_event_system.h	2011-04-20 10:50:56 UTC (rev 36241)
+++ trunk/blender/source/blender/windowmanager/wm_event_system.h	2011-04-20 11:15:58 UTC (rev 36242)
@@ -78,6 +78,8 @@
 /* handler flag */
 		/* after this handler all others are ignored */
 #define WM_HANDLER_BLOCKING		1
+		/* handler tagged to be freed in wm_handlers_do() */
+#define WM_HANDLER_DO_FREE		2
 
 
 




More information about the Bf-blender-cvs mailing list