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
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs