[Bf-blender-cvs] [16377abda8a] master: WM: initialize WM and deps before handling events

Campbell Barton noreply at git.blender.org
Fri Aug 25 12:25:34 CEST 2017


Commit: 16377abda8adb6444e888d1144d9225fa6415e65
Author: Campbell Barton
Date:   Fri Aug 25 20:26:52 2017 +1000
Branches: master
https://developer.blender.org/rB16377abda8adb6444e888d1144d9225fa6415e65

WM: initialize WM and deps before handling events

This avoids obscure bugs where operators could run from
events that happen before the UI and depsgraph have been initialized.

See: D2809 for details.

===================================================================

M	source/blender/windowmanager/intern/wm.c
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/wm_event_system.h

===================================================================

diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 1738dabde2d..a09cc4aeb31 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -495,6 +495,10 @@ void wm_close_and_free_all(bContext *C, ListBase *wmlist)
 
 void WM_main(bContext *C)
 {
+	/* Single refresh before handling events.
+	 * This ensures we don't run operators before the depsgraph has been evaluated. */
+	wm_event_do_refresh_wm_and_depsgraph(C);
+
 	while (1) {
 		
 		/* get events from ghost, handle window events, add to window queues */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 4f68e7cccca..7e7314cc0c8 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -263,13 +263,56 @@ static void wm_notifier_clear(wmNotifier *note)
 	memset(((char *)note) + sizeof(Link), 0, sizeof(*note) - sizeof(Link));
 }
 
+/**
+ * Was part of #wm_event_do_notifiers, split out so it can be called once before entering the #WM_main loop.
+ * This ensures operators don't run before the UI and depsgraph are initialized.
+ */
+void wm_event_do_refresh_wm_and_depsgraph(bContext *C)
+{
+	wmWindowManager *wm = CTX_wm_manager(C);
+	uint64_t win_combine_v3d_datamask = 0;
+
+	/* combine datamasks so 1 win doesn't disable UV's in another [#26448] */
+	for (wmWindow *win = wm->windows.first; win; win = win->next) {
+		win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen);
+	}
+
+	/* cached: editor refresh callbacks now, they get context */
+	for (wmWindow *win = wm->windows.first; win; win = win->next) {
+		ScrArea *sa;
+
+		CTX_wm_window_set(C, win);
+		for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+			if (sa->do_refresh) {
+				CTX_wm_area_set(C, sa);
+				ED_area_do_refresh(C, sa);
+			}
+		}
+
+		/* XXX make lock in future, or separated derivedmesh users in scene */
+		if (G.is_rendering == false) {
+			/* depsgraph & animation: update tagged datablocks */
+			Main *bmain = CTX_data_main(C);
+
+			/* copied to set's in scene_update_tagged_recursive() */
+			win->screen->scene->customdata_mask = win_combine_v3d_datamask;
+
+			/* XXX, hack so operators can enforce datamasks [#26482], gl render */
+			win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal;
+
+			BKE_scene_update_tagged(bmain->eval_ctx, bmain, win->screen->scene);
+		}
+	}
+
+	CTX_wm_window_set(C, NULL);
+}
+
 /* called in mainloop */
 void wm_event_do_notifiers(bContext *C)
 {
 	wmWindowManager *wm = CTX_wm_manager(C);
 	wmNotifier *note, *next;
 	wmWindow *win;
-	uint64_t win_combine_v3d_datamask = 0;
 	
 	if (wm == NULL)
 		return;
@@ -373,39 +416,7 @@ void wm_event_do_notifiers(bContext *C)
 		MEM_freeN(note);
 	}
 	
-	/* combine datamasks so 1 win doesn't disable UV's in another [#26448] */
-	for (win = wm->windows.first; win; win = win->next) {
-		win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen);
-	}
-
-	/* cached: editor refresh callbacks now, they get context */
-	for (win = wm->windows.first; win; win = win->next) {
-		ScrArea *sa;
-		
-		CTX_wm_window_set(C, win);
-		for (sa = win->screen->areabase.first; sa; sa = sa->next) {
-			if (sa->do_refresh) {
-				CTX_wm_area_set(C, sa);
-				ED_area_do_refresh(C, sa);
-			}
-		}
-		
-		/* XXX make lock in future, or separated derivedmesh users in scene */
-		if (G.is_rendering == false) {
-			/* depsgraph & animation: update tagged datablocks */
-			Main *bmain = CTX_data_main(C);
-
-			/* copied to set's in scene_update_tagged_recursive() */
-			win->screen->scene->customdata_mask = win_combine_v3d_datamask;
-
-			/* XXX, hack so operators can enforce datamasks [#26482], gl render */
-			win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal;
-
-			BKE_scene_update_tagged(bmain->eval_ctx, bmain, win->screen->scene);
-		}
-	}
-
-	CTX_wm_window_set(C, NULL);
+	wm_event_do_refresh_wm_and_depsgraph(C);
 }
 
 static int wm_event_always_pass(const wmEvent *event)
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index efc01b1f8a8..3fb9cd617bf 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -87,7 +87,8 @@ void        wm_event_do_handlers    (bContext *C);
 
 void        wm_event_add_ghostevent (wmWindowManager *wm, wmWindow *win, int type, int time, void *customdata);
 
-void        wm_event_do_notifiers   (bContext *C);
+void        wm_event_do_refresh_wm_and_depsgraph(bContext *C);
+void        wm_event_do_notifiers(bContext *C);
 
 /* wm_keymap.c */



More information about the Bf-blender-cvs mailing list