[Bf-blender-cvs] [f97fc5f7d7] workspaces: Support multi-window setups nicely

Julian Eisel noreply at git.blender.org
Tue Mar 14 13:00:31 CET 2017


Commit: f97fc5f7d7e1f404cea01ec18fb0de6d3c8e4bbf
Author: Julian Eisel
Date:   Tue Mar 14 12:46:49 2017 +0100
Branches: workspaces
https://developer.blender.org/rBf97fc5f7d7e1f404cea01ec18fb0de6d3c8e4bbf

Support multi-window setups nicely

Opening new windows now never duplicates the workspace, you can now
show the same workspace in multiple windows. The layout is per window
though, so you can have the same workspace active in multiple windows,
but use a different active layout.

Opening windows behaves as follows now:
* Adapt behavior of rB7bc76f8a3c1416b
* Duplicating an area into a new window creates a new screen-layout, we agreed this is probably what users would want.
* Creating a new temporary window (e.g. UserPrefs) adds a new hidden screen-layout
* Enabling multi-view time-sequential creates a new window but doesn't duplicate screen-layout anymore

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

M	source/blender/editors/workspace/screen_ops.c
M	source/blender/windowmanager/intern/wm_stereo.c
M	source/blender/windowmanager/intern/wm_window.c
M	source/blender/windowmanager/wm_window.h

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

diff --git a/source/blender/editors/workspace/screen_ops.c b/source/blender/editors/workspace/screen_ops.c
index 0b74aeaafd..3b72c5df2d 100644
--- a/source/blender/editors/workspace/screen_ops.c
+++ b/source/blender/editors/workspace/screen_ops.c
@@ -981,8 +981,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
 	wmWindow *newwin, *win = CTX_wm_window(C);
 	Scene *scene;
-	WorkSpace *workspace_old = WM_window_get_active_workspace(win);
-	WorkSpace *workspace_new;
+	WorkSpace *workspace = WM_window_get_active_workspace(win);
 	WorkSpaceLayout *layout_new;
 	bScreen *newsc, *sc;
 	ScrArea *sa;
@@ -1019,12 +1018,9 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 
 	newwin->scene = scene;
 
-	workspace_new = ED_workspace_add(CTX_data_main(C), BKE_workspace_name_get(workspace_old),
-	                                 BKE_workspace_render_layer_get(workspace_old));
-	WM_window_set_active_workspace(newwin, workspace_new);
-
+	WM_window_set_active_workspace(newwin, workspace);
 	/* allocs new screen and adds to newly created window, using window size */
-	layout_new = ED_workspace_layout_add(workspace_new, newwin, sc->id.name + 2);
+	layout_new = ED_workspace_layout_add(workspace, newwin, sc->id.name + 2);
 	newsc = BKE_workspace_layout_screen_get(layout_new);
 	WM_window_set_active_layout(newwin, layout_new);
 
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index bcd547a472..bfe5696add 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -509,7 +509,7 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
 	    prev_display_mode != win_src->stereo3d_format->display_mode)
 	{
 		/* in case the hardward supports pageflip but not the display */
-		if ((win_dst = wm_window_copy_test(C, win_src))) {
+		if ((win_dst = wm_window_copy_test(C, win_src, false))) {
 			/* pass */
 		}
 		else {
@@ -528,7 +528,7 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
 			ok = false;
 		}
 		/* pageflip requires a new window to be created with the proper OS flags */
-		else if ((win_dst = wm_window_copy_test(C, win_src))) {
+		else if ((win_dst = wm_window_copy_test(C, win_src, false))) {
 			if (wm_stereo3d_quadbuffer_supported()) {
 				BKE_report(op->reports, RPT_INFO, "Quad-buffer window successfully created");
 			}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 4ffda69d0b..6e37a94f24 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -274,12 +274,13 @@ static wmWindow *wm_window_new_test(bContext *C)
 }
 
 /* part of wm_window.c api */
-wmWindow *wm_window_copy(bContext *C, wmWindow *win_src)
+wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_layout)
 {
-	Main *bmain = CTX_data_main(C);
 	wmWindow *win_dst = wm_window_new(C);
-	WorkSpace *workspace_src = WM_window_get_active_workspace(win_src);
+	WorkSpace *workspace = WM_window_get_active_workspace(win_src);
+	WorkSpaceLayout *layout_old = WM_window_get_active_layout(win_src);
 	Scene *scene = WM_window_get_active_scene(win_src);
+	WorkSpaceLayout *layout_new;
 	bScreen *new_screen;
 
 	win_dst->posx = win_src->posx + 10;
@@ -288,7 +289,9 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src)
 	win_dst->sizey = win_src->sizey;
 
 	win_dst->scene = scene;
-	WM_window_set_active_workspace(win_dst, ED_workspace_duplicate(workspace_src, bmain, win_dst));
+	WM_window_set_active_workspace(win_dst, workspace);
+	layout_new = duplicate_layout ? ED_workspace_layout_duplicate(workspace, layout_old, win_dst) : layout_old;
+	WM_window_set_active_layout(win_dst, layout_new);
 	new_screen = WM_window_get_active_screen(win_dst);
 	BLI_strncpy(win_dst->screenname, new_screen->id.name + 2, sizeof(win_dst->screenname));
 
@@ -305,12 +308,12 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src)
  * A higher level version of copy that tests the new window can be added.
  * (called from the operator directly)
  */
-wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src)
+wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src, const bool duplicate_layout)
 {
 	wmWindowManager *wm = CTX_wm_manager(C);
 	wmWindow *win_dst;
 
-	win_dst = wm_window_copy(C, win_src);
+	win_dst = wm_window_copy(C, win_src, duplicate_layout);
 
 	WM_check(C);
 
@@ -693,7 +696,7 @@ wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type)
 	}
 
 	if (WM_window_get_active_workspace(win) == NULL) {
-		WorkSpace *workspace = ED_workspace_add(bmain, "Temp", scene->render_layers.first);
+		WorkSpace *workspace = WM_window_get_active_workspace(win_prev);
 		WM_window_set_active_workspace(win, workspace);
 	}
 
@@ -768,22 +771,40 @@ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
 	return OPERATOR_FINISHED;
 }
 
+static bScreen *wm_window_new_find_screen(wmOperator *op, WorkSpace *workspace)
+{
+	ListBase *listbase = BKE_workspace_layouts_get(workspace);
+	const int layout_id = RNA_enum_get(op->ptr, "screen");
+	int i = 0;
+
+	BKE_workspace_layout_iter_begin(layout, listbase->first)
+	{
+		if (i++ == layout_id) {
+			return BKE_workspace_layout_screen_get(layout);
+		}
+	}
+	BKE_workspace_layout_iter_end;
+
+	BLI_assert(0);
+	return NULL;
+}
+
 /* new window operator callback */
 int wm_window_new_exec(bContext *C, wmOperator *op)
 {
-	Main *bmain = CTX_data_main(C);
 	wmWindow *win_src = CTX_wm_window(C);
-	const int screen_id = RNA_enum_get(op->ptr, "screen");
-	bScreen *screen = BLI_findlink(&bmain->screen, screen_id);
+	WorkSpace *workspace = WM_window_get_active_workspace(win_src);
+	bScreen *screen = wm_window_new_find_screen(op, workspace);
 	wmWindow *win_dst;
 
 	if (screen->winid) {
 		/* Screen is already used, duplicate window and screen */
-		win_dst = wm_window_copy_test(C, win_src);
+		win_dst = wm_window_copy_test(C, win_src, true);
 	}
 	else if ((win_dst = wm_window_new_test(C))) {
-		/* New window with a different screen */
-		win_dst->screen = screen;
+		/* New window with a different screen but same workspace */
+		WM_window_set_active_workspace(win_dst, workspace);
+		WM_window_set_active_screen(win_dst, screen);
 		screen->winid = win_dst->winid;
 		CTX_wm_window_set(C, win_dst);
 		ED_screen_refresh(CTX_wm_manager(C), win_dst);
@@ -794,9 +815,11 @@ int wm_window_new_exec(bContext *C, wmOperator *op)
 
 int wm_window_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
-	Main *bmain = CTX_data_main(C);
+	wmWindow *win = CTX_wm_window(C);
+	WorkSpace *workspace = WM_window_get_active_workspace(win);
+	ListBase *listbase = BKE_workspace_layouts_get(workspace);
 
-	if (BLI_listbase_count_ex(&bmain->screen, 2) == 1) {
+	if (BLI_listbase_count_ex(listbase, 2) == 1) {
 		RNA_enum_set(op->ptr, "screen", 0);
 		return wm_window_new_exec(C, op);
 	}
@@ -808,7 +831,9 @@ int wm_window_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(even
 struct EnumPropertyItem *wm_window_new_screen_itemf(
         bContext *C, struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), bool *r_free)
 {
-	Main *bmain = CTX_data_main(C);
+	wmWindow *win = CTX_wm_window(C);
+	WorkSpace *workspace = WM_window_get_active_workspace(win);
+	ListBase *listbase = BKE_workspace_layouts_get(workspace);
 	EnumPropertyItem *item = NULL;
 	EnumPropertyItem tmp = {0, "", 0, "", ""};
 	int value = 0, totitem = 0;
@@ -817,7 +842,9 @@ struct EnumPropertyItem *wm_window_new_screen_itemf(
 	 * for dynamic strings in EnumPropertyItem.name to avoid this. */
 	static char active_screens[20][MAX_NAME + 12];
 
-	for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+	BKE_workspace_layout_iter_begin(layout, listbase->first)
+	{
+		bScreen *screen = BKE_workspace_layout_screen_get(layout);
 		if (screen->winid) {
 			BLI_snprintf(active_screens[count_act_screens], sizeof(*active_screens), "%s (Duplicate)",
 			             screen->id.name + 2);
@@ -835,6 +862,7 @@ struct EnumPropertyItem *wm_window_new_screen_itemf(
 		RNA_enum_item_add(&item, &totitem, &tmp);
 		value++;
 	}
+	BKE_workspace_layout_iter_end;
 
 	RNA_enum_item_end(&item, &totitem);
 	*r_free = true;
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 5a45cf718e..dc4c600337 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -46,8 +46,8 @@ void wm_get_screensize(int *r_width, int *r_height);
 void wm_get_desktopsize(int *r_width, int *r_height);
 
 wmWindow	*wm_window_new			(bContext *C);
-wmWindow	*wm_window_copy			(bContext *C, wmWindow *win_src);
-wmWindow	*wm_window_copy_test	(bContext *C, wmWindow *win_src);
+wmWindow	*wm_window_copy			(bContext *C, wmWindow *win_src, const bool duplicate_layout);
+wmWindow	*wm_window_copy_test	(bContext *C, wmWindow *win_src, const bool duplicate_layout);
 void		wm_window_free			(bContext *C, wmWindowManager *wm, wmWindow *win);
 void		wm_window_close			(bContext *C, wmWindowManager *wm, wmWindow *win);




More information about the Bf-blender-cvs mailing list