Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/editors/include/ED_scene.h5
-rw-r--r--source/blender/editors/include/ED_screen.h5
-rw-r--r--source/blender/editors/scene/scene_edit.c40
-rw-r--r--source/blender/editors/screen/screen_edit.c49
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/screen/workspace_edit.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c6
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_wm.c5
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/intern/wm.c9
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c15
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c4
-rw-r--r--source/blender/windowmanager/intern/wm_window.c161
-rw-r--r--source/blender/windowmanager/wm_window.h7
20 files changed, 203 insertions, 135 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a38384f8f2b..1b309d76f61 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -906,7 +906,7 @@ Object *BKE_scene_object_find_by_name(Scene *scene, const char *name)
/**
* Sets the active scene, mainly used when running in background mode (``--scene`` command line argument).
* This is also called to set the scene directly, bypassing windowing code.
- * Otherwise #WM_window_change_active_scene is used when changing scenes by the user.
+ * Otherwise #WM_window_set_active_scene is used when changing scenes by the user.
*/
void BKE_scene_set_background(Main *bmain, Scene *scene)
{
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2a48bf8fc5a..4fa897bb689 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6926,9 +6926,11 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
link_list(fd, &wm->windows);
for (win = wm->windows.first; win; win = win->next) {
- WorkSpaceInstanceHook *hook = win->workspace_hook;
+ win->parent = newdataadr(fd, win->parent);
+ WorkSpaceInstanceHook *hook = win->workspace_hook;
win->workspace_hook = newdataadr(fd, hook);
+
/* we need to restore a pointer to this later when reading workspaces, so store in global oldnew-map */
oldnewmap_insert(fd->globmap, hook, win->workspace_hook, 0);
diff --git a/source/blender/editors/include/ED_scene.h b/source/blender/editors/include/ED_scene.h
index 9b48187e541..116d9bd24fc 100644
--- a/source/blender/editors/include/ED_scene.h
+++ b/source/blender/editors/include/ED_scene.h
@@ -31,10 +31,7 @@ enum eSceneCopyMethod;
struct Scene *ED_scene_add(struct Main *bmain, struct bContext *C, struct wmWindow *win, enum eSceneCopyMethod method) ATTR_NONNULL();
bool ED_scene_delete(struct bContext *C, struct Main *bmain, struct wmWindow *win, struct Scene *scene) ATTR_NONNULL();
-void ED_scene_change_update(
- struct Main *bmain, struct bContext *C,
- struct wmWindow *win, const struct bScreen *screen,
- struct Scene *scene_old, struct Scene *scene_new) ATTR_NONNULL();
+void ED_scene_change_update(struct Main *bmain, struct Scene *scene, struct ViewLayer *layer) ATTR_NONNULL();
bool ED_scene_view_layer_delete(
struct Main *bmain, struct Scene *scene, struct ViewLayer *layer,
struct ReportList *reports) ATTR_NONNULL(1, 2, 3);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 1fdbd46bacf..cc80108e20c 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -184,10 +184,7 @@ void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
void ED_screen_ensure_updated(struct wmWindowManager *wm, struct wmWindow *win, struct bScreen *screen);
void ED_screen_do_listen(struct bContext *C, struct wmNotifier *note);
bool ED_screen_change(struct bContext *C, struct bScreen *sc);
-void ED_screen_update_after_scene_change(
- const struct bScreen *screen,
- struct Scene *scene_new,
- struct ViewLayer *view_layer);
+void ED_screen_scene_change(struct bContext *C, struct wmWindow *win, struct Scene *scene);
void ED_screen_set_active_region(struct bContext *C, struct wmWindow *win, const int xy[2]);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index 677fc0a068e..0ebbd770c9f 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -80,7 +80,7 @@ Scene *ED_scene_add(Main *bmain, bContext *C, wmWindow *win, eSceneCopyMethod me
}
}
- WM_window_change_active_scene(bmain, C, win, scene_new);
+ WM_window_set_active_scene(bmain, C, win, scene_new);
WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, scene_new);
@@ -102,7 +102,7 @@ bool ED_scene_delete(bContext *C, Main *bmain, wmWindow *win, Scene *scene)
else
return false;
- WM_window_change_active_scene(bmain, C, win, scene_new);
+ WM_window_set_active_scene(bmain, C, win, scene_new);
BKE_libblock_remap(bmain, scene, scene_new, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
@@ -114,43 +114,17 @@ bool ED_scene_delete(bContext *C, Main *bmain, wmWindow *win, Scene *scene)
return true;
}
-static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new)
+/* Depsgraph updates after scene becomes active in a window. */
+void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
{
- ViewLayer *layer_new = BKE_workspace_view_layer_exists(workspace, scene_new);
- return layer_new ? layer_new : BKE_view_layer_default_view(scene_new);
-}
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, layer, true);
-void ED_scene_change_update(
- Main *bmain, bContext *C,
- wmWindow *win, const bScreen *screen, Scene *UNUSED(scene_old), Scene *scene_new)
-{
- WorkSpace *workspace = CTX_wm_workspace(C);
- ViewLayer *layer_new = scene_change_get_new_view_layer(workspace, scene_new);
- Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene_new, layer_new, true);
- Object *obact_new = OBACT(layer_new);
- UNUSED_VARS(obact_new);
-
-#if 0
- /* mode syncing */
- eObjectMode object_mode_old = workspace->object_mode;
- ViewLayer *layer_old = BKE_view_layer_from_workspace_get(scene_old, workspace);
- Object *obact_old = OBACT(layer_old);
- UNUSED_VARS(obact_old, object_mode_old);
-#endif
-
- win->scene = scene_new;
- CTX_data_scene_set(C, scene_new);
- BKE_workspace_view_layer_set(workspace, layer_new, scene_new);
- BKE_scene_set_background(bmain, scene_new);
- DEG_graph_relations_update(depsgraph, bmain, scene_new, layer_new);
+ BKE_scene_set_background(bmain, scene);
+ DEG_graph_relations_update(depsgraph, bmain, scene, layer);
DEG_on_visible_update(bmain, false);
- ED_screen_update_after_scene_change(screen, scene_new, layer_new);
ED_render_engine_changed(bmain);
ED_update_for_newframe(bmain, depsgraph);
-
- /* complete redraw */
- WM_event_add_notifier(C, NC_WINDOW, NULL);
}
static bool view_layer_remove_poll(
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 6bc8a6c10cf..50609815168 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -477,8 +477,8 @@ void ED_screens_initialize(Main *bmain, wmWindowManager *wm)
wmWindow *win;
for (win = wm->windows.first; win; win = win->next) {
- if (WM_window_get_active_workspace(win) == NULL) {
- WM_window_set_active_workspace(win, bmain->workspaces.first);
+ if (BKE_workspace_active_get(win->workspace_hook) == NULL) {
+ BKE_workspace_active_set(win->workspace_hook, bmain->workspaces.first);
}
if (BLI_listbase_is_empty(&win->global_areas.areabase)) {
@@ -792,11 +792,19 @@ static void screen_global_statusbar_area_create(wmWindow *win)
void ED_screen_global_areas_create(wmWindow *win)
{
+ /* Don't create global areas for child windows. */
+ if (win->parent) {
+ return;
+ }
+
+ /* Don't create global area for temporary windows. */
bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
- if (screen->temp == 0) {
- screen_global_topbar_area_create(win);
- screen_global_statusbar_area_create(win);
+ if (screen->temp) {
+ return;
}
+
+ screen_global_topbar_area_create(win);
+ screen_global_statusbar_area_create(win);
}
@@ -936,13 +944,40 @@ static void screen_set_3dview_camera(Scene *scene, ViewLayer *view_layer, ScrAre
}
}
-void ED_screen_update_after_scene_change(const bScreen *screen, Scene *scene_new, ViewLayer *view_layer)
+static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new)
+{
+ ViewLayer *layer_new = BKE_workspace_view_layer_exists(workspace, scene_new);
+ return layer_new ? layer_new : BKE_view_layer_default_view(scene_new);
+}
+
+void ED_screen_scene_change(bContext *C, wmWindow *win, Scene *scene)
{
+ const bScreen *screen = WM_window_get_active_screen(win);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ ViewLayer *view_layer = scene_change_get_new_view_layer(workspace, scene);
+
+#if 0
+ /* mode syncing */
+ Object *obact_new = OBACT(view_layer);
+ UNUSED_VARS(obact_new);
+ eObjectMode object_mode_old = workspace->object_mode;
+ ViewLayer *layer_old = BKE_view_layer_from_workspace_get(scene_old, workspace);
+ Object *obact_old = OBACT(layer_old);
+ UNUSED_VARS(obact_old, object_mode_old);
+#endif
+
+ BKE_workspace_view_layer_set(workspace, view_layer, scene);
+
+ win->scene = scene;
+ if (CTX_wm_window(C) == win) {
+ CTX_data_scene_set(C, scene);
+ }
+
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
- screen_set_3dview_camera(scene_new, view_layer, sa, v3d);
+ screen_set_3dview_camera(scene, view_layer, sa, v3d);
}
}
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index a0e8357b8f3..ab0fbfacf93 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1130,7 +1130,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
newwin->scene = scene;
- WM_window_set_active_workspace(newwin, workspace);
+ BKE_workspace_active_set(newwin->workspace_hook, workspace);
/* allocs new screen and adds to newly created window, using window size */
layout_new = ED_workspace_layout_add(bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old));
newsc = BKE_workspace_layout_screen_get(layout_new);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 9d329355500..9ba9b70a6e8 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -191,8 +191,8 @@ bool ED_workspace_change(
BLI_assert(BKE_workspace_layout_screen_get(layout_new) == screen_new);
if (screen_new) {
- WM_window_set_active_layout(win, workspace_new, layout_new);
- WM_window_set_active_workspace(win, workspace_new);
+ BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace_new, layout_new);
+ BKE_workspace_active_set(win->workspace_hook, workspace_new);
/* update screen *after* changing workspace - which also causes the
* actual screen change and updates context (including CTX_wm_workspace) */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 6668ea1faeb..8a5df196c7b 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -262,7 +262,7 @@ static eOLDrawState tree_element_set_active_object(
sce = (Scene *)outliner_search_back(soops, te, ID_SCE);
if (sce && scene != sce) {
- WM_window_change_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
scene = sce;
}
@@ -431,7 +431,7 @@ static eOLDrawState tree_element_active_world(
if (set != OL_SETSEL_NONE) {
/* make new scene active */
if (sce && scene != sce) {
- WM_window_change_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
}
}
@@ -950,7 +950,7 @@ static void do_outliner_item_activate_tree_element(
/* editmode? */
if (te->idcode == ID_SCE) {
if (scene != (Scene *)tselem->id) {
- WM_window_change_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id);
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id);
}
}
else if (te->idcode == ID_GR) {
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 9952db5e652..b23ea8e4dae 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -580,7 +580,7 @@ void outliner_do_object_operation_ex(
// when objects selected in other scenes... dunno if that should be allowed
Scene *scene_owner = (Scene *)outliner_search_back(soops, te, ID_SCE);
if (scene_owner && scene_act != scene_owner) {
- WM_window_change_active_scene(CTX_data_main(C), C, CTX_wm_window(C), scene_owner);
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), scene_owner);
}
/* important to use 'scene_owner' not scene_act else deleting objects can crash.
* only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
@@ -956,7 +956,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
Scene *sce = scene; // to be able to delete, scenes are set...
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_select_cb);
if (scene != sce) {
- WM_window_change_active_scene(bmain, C, win, sce);
+ WM_window_set_active_scene(bmain, C, win, sce);
}
str = "Select Objects";
@@ -967,7 +967,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
Scene *sce = scene; // to be able to delete, scenes are set...
outliner_do_object_operation_ex(C, op->reports, scene, soops, &soops->tree, object_select_hierarchy_cb, false);
if (scene != sce) {
- WM_window_change_active_scene(bmain, C, win, sce);
+ WM_window_set_active_scene(bmain, C, win, sce);
}
str = "Select Object Hierarchy";
DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE);
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index c6ad1470561..0ef9e9b134a 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -186,8 +186,10 @@ typedef struct wmWindow {
void *ghostwin; /* don't want to include ghost.h stuff */
void *gwnctx; /* don't want to include gawin stuff */
- struct Scene *scene; /* The scene displayed in this window. */
- struct Scene *new_scene; /* temporary when switching */
+ struct wmWindow *parent; /* Parent window */
+
+ struct Scene *scene; /* The scene displayed in this window. */
+ struct Scene *new_scene; /* temporary when switching */
struct WorkSpaceInstanceHook *workspace_hook;
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index fff53aafcc7..5fca91064b6 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -185,7 +185,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
BPy_BEGIN_ALLOW_THREADS;
#endif
- WM_window_change_active_scene(bmain, C, win, scene_new);
+ WM_window_set_active_scene(bmain, C, win, scene_new);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 1c94582c57e..569bc20d435 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -675,7 +675,7 @@ static void rna_Window_scene_update(bContext *C, PointerRNA *ptr)
BPy_BEGIN_ALLOW_THREADS;
#endif
- WM_window_change_active_scene(bmain, C, win, win->new_scene);
+ WM_window_set_active_scene(bmain, C, win, win->new_scene);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
@@ -2041,6 +2041,9 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Window", "Open window");
RNA_def_struct_sdna(srna, "wmWindow");
+ prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Parent Window", "Active workspace and scene follow this window");
+
rna_def_window_stereo3d(brna);
prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 3d1ee273108..0ed23a8fb20 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -111,10 +111,10 @@ struct Scene *WM_windows_scene_get_from_screen(const struct wmWindowManager *wm,
struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
struct Scene *WM_window_get_active_scene(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
-void WM_window_change_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win,
+void WM_window_set_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win,
struct Scene *scene_new) ATTR_NONNULL();
struct WorkSpace *WM_window_get_active_workspace(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
-void WM_window_set_active_workspace(struct wmWindow *win, struct WorkSpace *workspace) ATTR_NONNULL(1);
+void WM_window_set_active_workspace(struct bContext *C, struct wmWindow *win, struct WorkSpace *workspace) ATTR_NONNULL(1);
struct WorkSpaceLayout *WM_window_get_active_layout(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
void WM_window_set_active_layout(
struct wmWindow *win, struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL(1);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 701ad49b520..9ef0883cbbf 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -461,10 +461,10 @@ void wm_add_default(Main *bmain, bContext *C)
WorkSpaceLayout *layout = BKE_workspace_layout_find_global(bmain, screen, &workspace);
CTX_wm_manager_set(C, wm);
- win = wm_window_new(C);
+ win = wm_window_new(C, NULL);
win->scene = CTX_data_scene(C);
- WM_window_set_active_workspace(win, workspace);
- WM_window_set_active_layout(win, workspace, layout);
+ BKE_workspace_active_set(win->workspace_hook, workspace);
+ BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace, layout);
screen->winid = win->winid;
wm->winactive = win;
@@ -484,7 +484,8 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
wm_autosave_timer_ended(wm);
while ((win = BLI_pophead(&wm->windows))) {
- WM_window_set_active_workspace(win, NULL); /* prevent draw clear to use screen */
+ /* prevent draw clear to use screen */
+ BKE_workspace_active_set(win->workspace_hook, NULL);
wm_window_free(C, wm, win);
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 6fd23dc6b08..3aee57d5801 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -384,7 +384,7 @@ void wm_event_do_notifiers(bContext *C)
UI_popup_handlers_remove_all(C, &win->modalhandlers);
- ED_workspace_change(ref_ws, C, wm, win);
+ WM_window_set_active_workspace(C, win, ref_ws);
if (G.debug & G_DEBUG_EVENTS)
printf("%s: Workspace set %p\n", __func__, note->reference);
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 5628d39e5f8..1983c0e6b84 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2298,7 +2298,7 @@ static void WM_OT_window_close(wmOperatorType *ot)
{
ot->name = "Close Window";
ot->idname = "WM_OT_window_close";
- ot->description = "Close the current Blender window";
+ ot->description = "Close the current window";
ot->exec = wm_window_close_exec;
ot->poll = WM_operator_winactive;
@@ -2308,12 +2308,22 @@ static void WM_OT_window_new(wmOperatorType *ot)
{
ot->name = "New Window";
ot->idname = "WM_OT_window_new";
- ot->description = "Create a new Blender window";
+ ot->description = "Create a new window";
ot->exec = wm_window_new_exec;
ot->poll = wm_operator_winactive_normal;
}
+static void WM_OT_window_new_main(wmOperatorType *ot)
+{
+ ot->name = "New Main Window";
+ ot->idname = "WM_OT_window_new_main";
+ ot->description = "Create a new main window with its own workspace and scene selection";
+
+ ot->exec = wm_window_new_main_exec;
+ ot->poll = wm_operator_winactive_normal;
+}
+
static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
{
ot->name = "Toggle Window Fullscreen";
@@ -3703,6 +3713,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_window_close);
WM_operatortype_append(WM_OT_window_new);
+ WM_operatortype_append(WM_OT_window_new_main);
WM_operatortype_append(WM_OT_read_history);
WM_operatortype_append(WM_OT_read_homefile);
WM_operatortype_append(WM_OT_read_factory_settings);
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 4450d18a5df..2c779ba9c7c 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -404,7 +404,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, false))) {
+ if ((win_dst = wm_window_copy_test(C, win_src, false, false))) {
/* pass */
}
else {
@@ -423,7 +423,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, false))) {
+ else if ((win_dst = wm_window_copy_test(C, win_src, false, 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 43231855162..d28d2c6b001 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -256,7 +256,7 @@ static int find_free_winid(wmWindowManager *wm)
}
/* don't change context itself */
-wmWindow *wm_window_new(bContext *C)
+wmWindow *wm_window_new(bContext *C, wmWindow *parent)
{
Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
@@ -265,6 +265,7 @@ wmWindow *wm_window_new(bContext *C)
BLI_addtail(&wm->windows, win);
win->winid = find_free_winid(wm);
+ win->parent = (parent && parent->parent) ? parent->parent : parent;
win->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo 3D Format (window)");
win->workspace_hook = BKE_workspace_instance_hook_create(bmain);
@@ -272,10 +273,11 @@ wmWindow *wm_window_new(bContext *C)
}
/* part of wm_window.c api */
-wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_layout)
+wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_layout, const bool child)
{
Main *bmain = CTX_data_main(C);
- wmWindow *win_dst = wm_window_new(C);
+ wmWindow *win_parent = (child) ? win_src : win_src->parent;
+ wmWindow *win_dst = wm_window_new(C, win_parent);
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);
@@ -287,9 +289,9 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_la
win_dst->sizey = win_src->sizey;
win_dst->scene = scene;
- WM_window_set_active_workspace(win_dst, workspace);
+ BKE_workspace_active_set(win_dst->workspace_hook, workspace);
layout_new = duplicate_layout ? ED_workspace_layout_duplicate(bmain, workspace, layout_old, win_dst) : layout_old;
- WM_window_set_active_layout(win_dst, workspace, layout_new);
+ BKE_workspace_hook_layout_for_workspace_set(win_dst->workspace_hook, workspace, layout_new);
*win_dst->stereo3d_format = *win_src->stereo3d_format;
@@ -300,12 +302,12 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_la
* 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, const bool duplicate_layout)
+wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src, const bool duplicate_layout, const bool child)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win_dst;
- win_dst = wm_window_copy(C, win_src, duplicate_layout);
+ win_dst = wm_window_copy(C, win_src, duplicate_layout, child);
WM_check(C);
@@ -473,56 +475,67 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmWindow *tmpwin;
- /* first check if we have to quit (there are non-temp remaining windows) */
- for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
- if (tmpwin == win)
- continue;
- if (WM_window_is_temp_screen(tmpwin) == false)
- break;
+ /* first check if we have to quit (there are non-temp and non-child windows remaining) */
+ if (win->parent == NULL) {
+ for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
+ if (tmpwin == win)
+ continue;
+ if (tmpwin->parent == NULL)
+ break;
+ if (WM_window_is_temp_screen(tmpwin) == false)
+ break;
+ }
+
+ if (tmpwin == NULL) {
+ wm_quit_with_optional_confirmation_prompt(C, win);
+ return;
+ }
}
- if (tmpwin == NULL) {
- wm_quit_with_optional_confirmation_prompt(C, win);
+ /* close child windows */
+ for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
+ if (tmpwin->parent == win) {
+ wm_window_close(C, wm, tmpwin);
+ }
}
- else {
- bScreen *screen = WM_window_get_active_screen(win);
- WorkSpace *workspace = WM_window_get_active_workspace(win);
- WorkSpaceLayout *layout = BKE_workspace_active_layout_get(win->workspace_hook);
- BLI_remlink(&wm->windows, win);
+ bScreen *screen = WM_window_get_active_screen(win);
+ WorkSpace *workspace = WM_window_get_active_workspace(win);
+ WorkSpaceLayout *layout = BKE_workspace_active_layout_get(win->workspace_hook);
- CTX_wm_window_set(C, win); /* needed by handlers */
- WM_event_remove_handlers(C, &win->handlers);
- WM_event_remove_handlers(C, &win->modalhandlers);
+ BLI_remlink(&wm->windows, win);
- /* for regular use this will _never_ be NULL,
- * however we may be freeing an improperly initialized window. */
- if (screen) {
- ED_screen_exit(C, win, screen);
- }
+ CTX_wm_window_set(C, win); /* needed by handlers */
+ WM_event_remove_handlers(C, &win->handlers);
+ WM_event_remove_handlers(C, &win->modalhandlers);
- if (tmpwin) {
- BLF_batch_reset();
- gpu_batch_presets_reset();
- immDeactivate();
- }
+ /* for regular use this will _never_ be NULL,
+ * however we may be freeing an improperly initialized window. */
+ if (screen) {
+ ED_screen_exit(C, win, screen);
+ }
- wm_window_free(C, wm, win);
+ if (tmpwin) {
+ BLF_batch_reset();
+ gpu_batch_presets_reset();
+ immDeactivate();
+ }
- /* keep imediatemode active before the next `wm_window_make_drawable` call */
- if (tmpwin) {
- GHOST_ActivateWindowDrawingContext(tmpwin->ghostwin);
- GWN_context_active_set(tmpwin->gwnctx);
- immActivate();
- }
+ wm_window_free(C, wm, win);
+
+ /* keep imediatemode active before the next `wm_window_make_drawable` call */
+ if (tmpwin) {
+ GHOST_ActivateWindowDrawingContext(tmpwin->ghostwin);
+ GWN_context_active_set(tmpwin->gwnctx);
+ immActivate();
+ }
- /* if temp screen, delete it after window free (it stops jobs that can access it) */
- if (screen && screen->temp) {
- Main *bmain = CTX_data_main(C);
+ /* if temp screen, delete it after window free (it stops jobs that can access it) */
+ if (screen && screen->temp) {
+ Main *bmain = CTX_data_main(C);
- BLI_assert(BKE_workspace_layout_screen_get(layout) == screen);
- BKE_workspace_layout_remove(bmain, workspace, layout);
- }
+ BLI_assert(BKE_workspace_layout_screen_get(layout) == screen);
+ BKE_workspace_layout_remove(bmain, workspace, layout);
}
}
@@ -809,7 +822,7 @@ void wm_window_ghostwindows_remove_invalid(bContext *C, wmWindowManager *wm)
wmWindow *WM_window_open(bContext *C, const rcti *rect)
{
wmWindow *win_prev = CTX_wm_window(C);
- wmWindow *win = wm_window_new(C);
+ wmWindow *win = wm_window_new(C, win_prev);
win->posx = rect->xmin;
win->posy = rect->ymin;
@@ -869,7 +882,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
/* add new window? */
if (win == NULL) {
- win = wm_window_new(C);
+ win = wm_window_new(C, win_prev);
win->posx = rect.xmin;
win->posy = rect.ymin;
@@ -887,7 +900,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
if (WM_window_get_active_workspace(win) == NULL) {
WorkSpace *workspace = WM_window_get_active_workspace(win_prev);
- WM_window_set_active_workspace(win, workspace);
+ BKE_workspace_active_set(win->workspace_hook, workspace);
}
if (screen == NULL) {
@@ -904,7 +917,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
}
/* In case we reuse an already existing temp window (see win lookup above). */
else if (WM_window_get_active_scene(win) != scene) {
- WM_window_change_active_scene(bmain, C, win, scene);
+ WM_window_set_active_scene(bmain, C, win, scene);
}
screen->temp = 1;
@@ -976,17 +989,25 @@ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-/* operator callback */
int wm_window_new_exec(bContext *C, wmOperator *UNUSED(op))
{
wmWindow *win_src = CTX_wm_window(C);
bool ok;
- ok = (wm_window_copy_test(C, win_src, true) != NULL);
+ ok = (wm_window_copy_test(C, win_src, true, true) != NULL);
return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+int wm_window_new_main_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ wmWindow *win_src = CTX_wm_window(C);
+ bool ok;
+
+ ok = (wm_window_copy_test(C, win_src, true, false) != NULL);
+
+ return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+}
/* fullscreen operator callback */
int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
@@ -2103,21 +2124,45 @@ Scene *WM_window_get_active_scene(const wmWindow *win)
/**
* \warning Only call outside of area/region loops
*/
-void WM_window_change_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene *scene_new)
+void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene *scene)
{
- const bScreen *screen = WM_window_get_active_screen(win);
- Scene *scene_old = win->scene;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win_parent = (win->parent) ? win->parent : win;
- ED_scene_change_update(bmain, C, win, screen, scene_old, scene_new);
+ /* Set scene in parent and its child windows. */
+ ED_screen_scene_change(C, win_parent, scene);
+
+ for (wmWindow *win_child = wm->windows.first; win_child; win_child = win_child->next) {
+ if (win_child->parent == win_parent) {
+ ED_screen_scene_change(C, win_child, scene);
+ }
+ }
+
+ /* Update depsgraph and renderers for scene change. */
+ ViewLayer *view_layer = WM_window_get_active_view_layer(win_parent);
+ ED_scene_change_update(bmain, scene, view_layer);
+
+ /* Complete redraw. */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
}
WorkSpace *WM_window_get_active_workspace(const wmWindow *win)
{
return BKE_workspace_active_get(win->workspace_hook);
}
-void WM_window_set_active_workspace(wmWindow *win, WorkSpace *workspace)
+
+void WM_window_set_active_workspace(bContext *C, wmWindow *win, WorkSpace *workspace)
{
- BKE_workspace_active_set(win->workspace_hook, workspace);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win_parent = (win->parent) ? win->parent : win;
+
+ ED_workspace_change(workspace, C, wm, win);
+
+ for (wmWindow *win_child = wm->windows.first; win_child; win_child = win_child->next) {
+ if (win_child->parent == win_parent) {
+ ED_workspace_change(workspace, C, wm, win_child);
+ }
+ }
}
WorkSpaceLayout *WM_window_get_active_layout(const wmWindow *win)
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 952ffe5c117..385d61217ad 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -45,9 +45,9 @@ void wm_ghost_exit(void);
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, const bool duplicate_layout);
-wmWindow *wm_window_copy_test (bContext *C, wmWindow *win_src, const bool duplicate_layout);
+wmWindow *wm_window_new (bContext *C, wmWindow *parent);
+wmWindow *wm_window_copy (bContext *C, wmWindow *win_src, const bool duplicate_layout, const bool child);
+wmWindow *wm_window_copy_test (bContext *C, wmWindow *win_src, const bool duplicate_layout, const bool child);
void wm_window_free (bContext *C, wmWindowManager *wm, wmWindow *win);
void wm_window_close (bContext *C, wmWindowManager *wm, wmWindow *win);
@@ -85,6 +85,7 @@ int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
void wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win) ATTR_NONNULL();
int wm_window_new_exec(bContext *C, struct wmOperator *op);
+int wm_window_new_main_exec(bContext *C, struct wmOperator *op);
/* Initial (unmaximized) size to start with for
* systems that can't find it for themselves (X11).