[Bf-blender-cvs] [db07bce] workspaces: Fix crash when toggling area fullscreen

Julian Eisel noreply at git.blender.org
Tue Dec 6 02:42:44 CET 2016


Commit: db07bce54fbf681a0259e898ede1f16bf8a3d021
Author: Julian Eisel
Date:   Tue Dec 6 02:42:05 2016 +0100
Branches: workspaces
https://developer.blender.org/rBdb07bce54fbf681a0259e898ede1f16bf8a3d021

Fix crash when toggling area fullscreen

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

M	source/blender/blenkernel/BKE_workspace.h
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/screen/screen_edit.c
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/screen/workspace_edit.c
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_window.c

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

diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 96ef529..0529297 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -39,6 +39,7 @@ struct WorkSpace *BKE_workspace_duplicate(Main *bmain, const struct WorkSpace *f
 void BKE_workspace_free(struct WorkSpace *ws);
 
 struct WorkSpaceLayout *BKE_workspace_layout_add(struct WorkSpace *workspace, struct bScreen *screen) ATTR_NONNULL();
+void BKE_workspace_layout_remove(struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL();
 
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 176e2da..933b77a 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -82,6 +82,12 @@ WorkSpaceLayout *BKE_workspace_layout_add(WorkSpace *workspace, bScreen *screen)
 	return layout;
 }
 
+void BKE_workspace_layout_remove(WorkSpace *workspace, WorkSpaceLayout *layout)
+{
+	BLI_remlink(&workspace->layouts, layout);
+	MEM_freeN(layout);
+}
+
 
 /* -------------------------------------------------------------------- */
 /* General Utils */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 0297e5e..a2c1ef7 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -105,7 +105,7 @@ void    ED_screen_draw(struct wmWindow *win);
 void    ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
 void    ED_screen_do_listen(struct bContext *C, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc, WorkSpaceLayout **r_layout);
-bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name);
+bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name, WorkSpaceLayout **r_layout);
 bool    ED_screen_set(struct bContext *C, struct bScreen *sc);
 bool    ED_screen_delete(struct bContext *C, struct bScreen *sc);
 void    ED_screen_set_scene(struct bContext *C, struct bScreen *screen, struct Scene *scene);
@@ -127,7 +127,7 @@ void    ED_screen_preview_render(const struct bScreen *screen, int size_x, int s
 bool ED_workspace_change(struct bContext *C, struct wmWindow *win, WorkSpace *ws_new) ATTR_NONNULL();
 WorkSpace *ED_workspace_duplicate(struct Main *bmain, struct wmWindow *win);
 bool ED_workspace_delete(struct Main *bmain, struct bContext *C, struct wmWindow *win, WorkSpace *ws);
-bool ED_workspace_layout_circle(struct bContext *C, struct wmWindow *win, const short direction) ATTR_NONNULL();
+bool ED_workspace_layout_cycle(struct bContext *C, struct wmWindow *win, const short direction) ATTR_NONNULL();
 
 /* anim */
 void    ED_update_for_newframe(struct Main *bmain, struct Scene *scene, int mute);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 8b8642b..34df34d 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -459,9 +459,11 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
 	return newa;
 }
 
-/* empty screen, with 1 dummy area without spacedata */
-/* uses window size */
-bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
+/**
+ * Empty screen, with 1 dummy area without spacedata. Uses window size.
+ * \param r_layout: The layout wrapper created for \a sc. Can be NULL to skip layout creation.
+ */
+bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name, WorkSpaceLayout **r_layout)
 {
 	const int winsize_x = WM_window_pixels_x(win);
 	const int winsize_y = WM_window_pixels_y(win);
@@ -487,7 +489,11 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
 	
 	/* dummy type, no spacedata */
 	screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_EMPTY);
-		
+
+	if (r_layout) {
+		*r_layout = BKE_workspace_layout_add(win->workspace, sc);
+	}
+
 	return sc;
 }
 
@@ -1062,14 +1068,10 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc, WorkSpaceLayout **r_lay
 	if (sc->state != SCREENNORMAL) return NULL;  /* XXX handle this case! */
 
 	/* make new empty screen: */
-	newsc = ED_screen_add(win, sc->scene, sc->id.name + 2);
+	newsc = ED_screen_add(win, sc->scene, sc->id.name + 2, r_layout);
 	/* copy all data */
 	screen_copy(newsc, sc);
 
-	if (r_layout) {
-		*r_layout = BKE_workspace_layout_add(win->workspace, newsc);
-	}
-
 	return newsc;
 }
 
@@ -1954,6 +1956,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
 	}
 
 	if (sa && sa->full) {
+		WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
 		/* restoring back to SCREENNORMAL */
 		ScrArea *old;
 
@@ -1988,6 +1991,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
 
 		ED_screen_set(C, sc);
 
+		BKE_workspace_layout_remove(win->workspace, layout_old);
 		BKE_screen_free(oldscreen);
 		BKE_libblock_free(CTX_data_main(C), oldscreen);
 
@@ -1999,6 +2003,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
 	}
 	else {
 		/* change from SCREENNORMAL to new state */
+		WorkSpaceLayout *layout_new;
 		ScrArea *newa;
 		char newname[MAX_ID_NAME - 2];
 
@@ -2006,7 +2011,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
 
 		oldscreen->state = state;
 		BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal");
-		sc = ED_screen_add(win, oldscreen->scene, newname);
+		sc = ED_screen_add(win, oldscreen->scene, newname, &layout_new);
 		sc->state = state;
 		sc->redraws_flag = oldscreen->redraws_flag;
 		sc->temp = oldscreen->temp;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 15f8719..343557e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -980,6 +980,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
 static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
 	wmWindow *newwin, *win;
+	WorkSpaceLayout *layout;
 	bScreen *newsc, *sc;
 	ScrArea *sa;
 	rcti rect;
@@ -1014,8 +1015,8 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 
 	newwin->workspace = win->workspace;
 	/* allocs new screen and adds to newly created window, using window size */
-	newsc = ED_screen_add(newwin, CTX_data_scene(C), sc->id.name + 2);
-	WM_window_set_active_screen(newwin, newsc);
+	newsc = ED_screen_add(newwin, CTX_data_scene(C), sc->id.name + 2, &layout);
+	WM_window_set_active_layout(newwin, layout);
 
 	/* copy area to new screen */
 	ED_area_data_copy((ScrArea *)newsc->areabase.first, sa, true);
@@ -2392,7 +2393,7 @@ static int screen_set_exec(bContext *C, wmOperator *op)
 	wmWindow *win = CTX_wm_window(C);
 	int delta = RNA_int_get(op->ptr, "delta");
 
-	if (ED_workspace_layout_circle(C, win, delta)) {
+	if (ED_workspace_layout_cycle(C, win, delta)) {
 		return OPERATOR_FINISHED;
 	}
 
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index ba8085b..cf9e48a 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -121,7 +121,7 @@ static bool workspace_layout_set_poll(const WorkSpaceLayout *layout)
 	        (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT)));
 }
 
-bool ED_workspace_layout_circle(bContext *C, wmWindow *win, const short direction)
+bool ED_workspace_layout_cycle(bContext *C, wmWindow *win, const short direction)
 {
 	const WorkSpace *workspace = win->workspace;
 	WorkSpaceLayout *old_layout = WM_window_get_active_layout(win);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 16fce26..13e0b73 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2479,6 +2479,9 @@ void wm_event_do_handlers(bContext *C)
 		while ( (event = win->queue.first) ) {
 			int action = WM_HANDLER_CONTINUE;
 
+			/* active screen might change during handlers, update pointer */
+			screen = WM_window_get_active_screen(win);
+
 			if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
 				printf("\n%s: Handling event\n", __func__);
 				WM_event_print(event);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 9adee49..a1172e5 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -661,9 +661,10 @@ wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type)
 	}
 
 	if (screen == NULL) {
-		screen = ED_screen_add(win, scene, "temp");
 		/* add new screen */
-		WM_window_set_active_screen(win, screen);
+		WorkSpaceLayout *layout;
+		screen = ED_screen_add(win, scene, "temp", &layout);
+		WM_window_set_active_layout(win, layout);
 	}
 	else {
 		/* switch scene for rendering */




More information about the Bf-blender-cvs mailing list