[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25941] trunk/blender/source/blender: [ #20093] Consistent Crash in properties window

Martin Poirier theeth at yahoo.com
Wed Jan 13 00:30:20 CET 2010


Revision: 25941
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25941
Author:   theeth
Date:     2010-01-13 00:30:19 +0100 (Wed, 13 Jan 2010)

Log Message:
-----------
[#20093] Consistent Crash in properties window

Fun bug, took me the better part of the day to track down.

Happens because maximizing swaps spacedata lists between the old area and the newly created maximized area (this one being empty) while ui handlers are still hanging with references to the first area (then trying to access spacedata when handled). And then only if a maximizing operator was run before the UI realign timer event from the previous maximize was handled (fun, I told you).

After discussion with Matt on irc, we decided the best way to deal with that was to remove ui handlers that reference areas of a screen that is no longer used. That solution reflects the fact that the bug is more general that the reproducing steps would lead to believe. There's also absolutely no reason to run UI handlers on invisible areas.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/screen/screen_edit.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c

Modified: trunk/blender/source/blender/editors/screen/screen_edit.c
===================================================================
--- trunk/blender/source/blender/editors/screen/screen_edit.c	2010-01-12 21:20:09 UTC (rev 25940)
+++ trunk/blender/source/blender/editors/screen/screen_edit.c	2010-01-12 23:30:19 UTC (rev 25941)
@@ -1271,7 +1271,13 @@
 	
 	if (oldscreen != sc) {
 		wmTimer *wt= oldscreen->animtimer;
-		
+		ScrArea *sa;
+
+		/* remove handlers referencing areas in old screen */
+		for(sa = oldscreen->areabase.first; sa; sa = sa->next) {
+			WM_event_remove_area_handler(&win->modalhandlers, sa);
+		}
+
 		/* we put timer to sleep, so screen_exit has to think there's no timer */
 		oldscreen->animtimer= NULL;
 		if(wt)

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h	2010-01-12 21:20:09 UTC (rev 25940)
+++ trunk/blender/source/blender/windowmanager/WM_api.h	2010-01-12 23:30:19 UTC (rev 25941)
@@ -150,6 +150,7 @@
 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		WM_event_remove_area_handler(struct ListBase *handlers, void *area);
 
 struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
 void		WM_event_remove_handlers(struct bContext *C, ListBase *handlers);

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2010-01-12 21:20:09 UTC (rev 25940)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2010-01-12 23:30:19 UTC (rev 25941)
@@ -1620,6 +1620,25 @@
 	}
 }
 
+void WM_event_remove_area_handler(ListBase *handlers, void *area)
+{
+	wmEventHandler *handler, *nexthandler;
+
+	for(handler = handlers->first; handler; handler= nexthandler) {
+		nexthandler = handler->next;
+		if (handler->ui_area == area || handler->op_area == area) {
+			BLI_remlink(handlers, handler);
+			wm_event_free_handler(handler);
+		}
+	}
+}
+
+void WM_event_remove_handler(ListBase *handlers, wmEventHandler *handler)
+{
+	BLI_remlink(handlers, handler);
+	wm_event_free_handler(handler);
+}
+
 void WM_event_add_mousemove(bContext *C)
 {
 	wmWindow *window= CTX_wm_window(C);





More information about the Bf-blender-cvs mailing list