[Bf-blender-cvs] [e38481e53b8] workspaces: Fix for crash loading a file containing a temp (maximized) screen.

Campbell Barton noreply at git.blender.org
Mon May 1 22:42:54 CEST 2017


Commit: e38481e53b84db4f00b01bf350d51e01ee2759d1
Author: Campbell Barton
Date:   Tue May 2 06:46:20 2017 +1000
Branches: workspaces
https://developer.blender.org/rBe38481e53b84db4f00b01bf350d51e01ee2759d1

Fix for crash loading a file containing a temp (maximized) screen.

Not pretty, we need to remove temp workspaces after creating them
because of order-of-initialization logic here, see: D2451#62433

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

M	source/blender/blenkernel/BKE_workspace.h
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/blenloader/intern/versioning_280.c

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

diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 52aa06aa97c..abca20ed04e 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -66,6 +66,8 @@ void BKE_workspace_layout_remove(
         WorkSpace *workspace, WorkSpaceLayout *layout,
         struct Main *bmain) ATTR_NONNULL();
 
+void BKE_workspace_layouts_transfer(
+        WorkSpace *workspace_dst, WorkSpace *workspace_src) ATTR_NONNULL();
 
 /* -------------------------------------------------------------------- */
 /* General Utils */
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 07a5e2eae5b..9faf075af85 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -233,6 +233,12 @@ void BKE_workspace_layout_remove(
 	BLI_freelinkN(&workspace->layouts, layout);
 }
 
+void BKE_workspace_layouts_transfer(
+        WorkSpace *workspace_dst, WorkSpace *workspace_src)
+{
+	BLI_movelisttolist(&workspace_dst->layouts, &workspace_src->layouts);
+
+}
 
 /* -------------------------------------------------------------------- */
 /* General Utils */
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 14ad2ee2282..d620b2f1b29 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -52,6 +52,17 @@
 
 #include "MEM_guardedalloc.h"
 
+
+static bScreen *screen_parent_get(bScreen *screen)
+{
+	for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+		if (sa->full && sa->full != screen) {
+			return sa->full;
+		}
+	}
+	return NULL;
+}
+
 /**
  * \brief Before lib-link versioning for new workspace design.
  *
@@ -65,6 +76,10 @@ static void do_version_workspaces_before_lib_link(Main *main)
 	BLI_assert(BLI_listbase_is_empty(&main->workspaces));
 
 	for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+
+		// XXX, ideally we would use screen_get_unique_full here to avoid loading some screens.
+		// but we didn't link yet so we can't tell .
+
 		WorkSpace *ws = BKE_workspace_add(main, screen->id.name + 2);
 		BKE_workspace_layout_add(ws, screen, screen->id.name + 2);
 
@@ -87,29 +102,58 @@ static void do_version_workspaces_before_lib_link(Main *main)
  *     here we need to find and activate the workspace that contains the active screen of the old file.
  *  *  Active scene isn't stored in screen anymore, but in window.
  */
-static void do_version_workspaces_after_lib_link(Main *main)
+static void do_version_workspaces_after_lib_link(Main *bmain)
 {
-	for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
-		WorkSpace *workspace = BLI_findstring(&main->workspaces, screen->id.name + 2, offsetof(ID, name) + 2);
-
+	for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+		WorkSpace *workspace = BLI_findstring(&bmain->workspaces, screen->id.name + 2, offsetof(ID, name) + 2);
 		BKE_workspace_render_layer_set(workspace, screen->scene->render_layers.first);
 	}
 
-	for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) {
+	bool has_temp_workspaces = false;
+
+	for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
 		for (wmWindow *win = wm->windows.first; win; win = win->next) {
 			bScreen *screen = win->screen;
-			WorkSpace *workspace = BLI_findstring(&main->workspaces, screen->id.name + 2, offsetof(ID, name) + 2);
+			bScreen *screen_parent = screen_parent_get(screen);
+			WorkSpace *workspace = BLI_findstring(&bmain->workspaces, screen->id.name + 2, offsetof(ID, name) + 2);
+
+			if (screen_parent) {
+				WorkSpace *workspace_parent = BLI_findstring(
+				        &bmain->workspaces, screen_parent->id.name + 2, offsetof(ID, name) + 2);
+				BKE_workspace_layouts_transfer(workspace_parent, workspace);
+
+				workspace = workspace_parent;
+
+				has_temp_workspaces = true;
+			}
+
 			ListBase *layouts = BKE_workspace_layouts_get(workspace);
 
 			BKE_workspace_active_set(win->workspace_hook, workspace);
 			win->scene = screen->scene;
-			BKE_workspace_active_layout_set(win->workspace_hook, layouts->first);
+
+			/* use last so the workspace_parent layout is used if it was added. */
+			BKE_workspace_active_layout_set(win->workspace_hook, layouts->last);
 
 			/* Deprecated from now on! */
 			win->screen = NULL;
 			screen->scene = NULL;
 		}
 	}
+
+	/* Cleanup workspaces from temp screens */
+	if (has_temp_workspaces) {
+		for (ID *workspace = bmain->workspaces.first, *workspace_next;
+		     workspace;
+		     workspace = workspace_next)
+		{
+			workspace_next = workspace->next;
+			ListBase *layouts = BKE_workspace_layouts_get((WorkSpace *)workspace);
+			if (BLI_listbase_is_empty(layouts)) {
+				BKE_workspace_remove((WorkSpace *)workspace, bmain);
+			}
+		}
+	}
 }
 
 void do_versions_after_linking_280(Main *main)




More information about the Bf-blender-cvs mailing list