Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 6 Jun 2018 14:25:28 +0000 (16:25 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 6 Jun 2018 14:25:28 +0000 (16:25 +0200)
 Conflicts:
source/blender/collada/ArmatureExporter.cpp
source/blender/collada/ArmatureExporter.h
source/blender/collada/DocumentExporter.cpp
source/blender/collada/DocumentExporter.h
source/blender/collada/SceneExporter.cpp
source/blender/collada/SceneExporter.h
source/blender/collada/collada.cpp
source/blender/collada/collada.h
source/blender/editors/armature/armature_edit.c
source/blender/editors/armature/editarmature_retarget.c
source/blender/editors/armature/pose_transform.c
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_object.h
source/blender/editors/include/ED_screen.h
source/blender/editors/io/io_collada.c
source/blender/editors/object/object_transform.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_window.c
source/blenderplayer/bad_level_call_stubs/stubs.c

33 files changed:
1  2 
source/blender/collada/ArmatureExporter.cpp
source/blender/collada/ArmatureExporter.h
source/blender/collada/ArmatureImporter.cpp
source/blender/collada/ArmatureImporter.h
source/blender/collada/DocumentExporter.cpp
source/blender/collada/DocumentExporter.h
source/blender/collada/SceneExporter.cpp
source/blender/collada/SceneExporter.h
source/blender/collada/collada.cpp
source/blender/collada/collada.h
source/blender/editors/armature/armature_edit.c
source/blender/editors/armature/armature_relations.c
source/blender/editors/armature/armature_utils.c
source/blender/editors/armature/pose_transform.c
source/blender/editors/curve/editcurve.c
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_object.h
source/blender/editors/include/ED_screen.h
source/blender/editors/io/io_collada.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_modes.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_transform.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_intern.h
source/blender/editors/screen/workspace_layout_edit.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_object.c
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_files.c

@@@ -62,10 -62,11 +62,11 @@@ ArmatureExporter::ArmatureExporter(COLL
  }
  
  // write bone nodes
- void ArmatureExporter::add_armature_bones(Depsgraph *depsgraph, Object *ob_arm,
 -void ArmatureExporter::add_armature_bones(bContext *C, Object *ob_arm, Scene *sce,
 -                                          SceneExporter *se,
++void ArmatureExporter::add_armature_bones(bContext *C, Depsgraph *depsgraph, Object *ob_arm,
 +                                          Scene *sce, SceneExporter *se,
                                            std::list<Object *>& child_objects)
  {
+       Main *bmain = CTX_data_main(C);
        // write bone nodes
  
        bArmature * armature = (bArmature *)ob_arm->data;
@@@ -77,7 -78,7 +78,7 @@@
        for (Bone *bone = (Bone *)armature->bonebase.first; bone; bone = bone->next) {
                // start from root bones
                if (!bone->parent)
-                       add_bone_node(depsgraph, bone, ob_arm, sce, se, child_objects);
 -                      add_bone_node(C, bone, ob_arm, sce, se, child_objects);
++                      add_bone_node(C, depsgraph, bone, ob_arm, sce, se, child_objects);
        }
  
        if (!is_edited) {
@@@ -157,7 -161,7 +158,7 @@@ void ArmatureExporter::find_objects_usi
  #endif
  
  // parent_mat is armature-space
- void ArmatureExporter::add_bone_node(Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce,
 -void ArmatureExporter::add_bone_node(bContext *C, Bone *bone, Object *ob_arm, Scene *sce,
++void ArmatureExporter::add_bone_node(bContext *C, Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce,
                                       SceneExporter *se,
                                       std::list<Object *>& child_objects)
  {
                                                mul_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv);
                                        }
  
-                                       se->writeNodes(depsgraph, *i, sce);
 -                                      se->writeNodes(C, *i, sce);
++                                      se->writeNodes(C, depsgraph, *i, sce);
  
                                        copy_m4_m4((*i)->parentinv, backup_parinv);
                                        child_objects.erase(i++);
                        }
  
                        for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
-                               add_bone_node(depsgraph, child, ob_arm, sce, se, child_objects);
 -                              add_bone_node(C, child, ob_arm, sce, se, child_objects);
++                              add_bone_node(C, depsgraph, child, ob_arm, sce, se, child_objects);
                        }
                        node.end();
                }
                else {
                        for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
-                               add_bone_node(depsgraph, child, ob_arm, sce, se, child_objects);
 -                              add_bone_node(C, child, ob_arm, sce, se, child_objects);
++                              add_bone_node(C, depsgraph, child, ob_arm, sce, se, child_objects);
                        }
                }
  }
@@@ -60,7 -60,7 +60,7 @@@ public
        ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
  
        // write bone nodes
-       void add_armature_bones(struct Depsgraph *depsgraph, Object *ob_arm, Scene *sce, SceneExporter *se,
 -      void add_armature_bones(bContext *C, Object *ob_arm, Scene *sce, SceneExporter *se,
++      void add_armature_bones(bContext *C, struct Depsgraph *depsgraph, Object *ob_arm, Scene *sce, SceneExporter *se,
                                std::list<Object *>& child_objects);
  
        bool add_instance_controller(Object *ob);
@@@ -85,7 -85,7 +85,7 @@@ private
  
        // Scene, SceneExporter and the list of child_objects
        // are required for writing bone parented objects
-       void add_bone_node(struct Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
 -      void add_bone_node(bContext *C, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
++      void add_bone_node(bContext *C, struct Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
                           std::list<Object *>& child_objects);
  
        void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
@@@ -627,10 -625,10 +627,10 @@@ Object *ArmatureImporter::create_armatu
                connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
        }
        fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
-       ED_armature_from_edit(armature);
+       ED_armature_from_edit(bmain, armature);
        ED_armature_edit_free(armature);
  
 -      DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
 +      DEG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
  
        return ob_arm;
  }
@@@ -180,8 -181,7 +180,8 @@@ static COLLADABU::NativeString make_tem
  // COLLADA allows this through multiple <channel>s in <animation>.
  // For this to work, we need to know objects that use a certain action.
  
 -int DocumentExporter::exportCurrentScene(bContext *C, const EvaluationContext *eval_ctx, Scene *sce)
 +
- int DocumentExporter::exportCurrentScene(Scene *sce)
++int DocumentExporter::exportCurrentScene(bContext *C, Scene *sce)
  {
        PointerRNA sceneptr, unit_settings;
        PropertyRNA *system; /* unused , *scale; */
  
        if (this->export_settings->include_animations) {
                // <library_animations>
 -              AnimationExporter ae(writer, this->export_settings);
 +              AnimationExporter ae(depsgraph, writer, this->export_settings);
                ae.exportAnimations(sce);
        }
-       se.exportScene(depsgraph, sce);
 -      se.exportScene(C, sce);
++      se.exportScene(C, depsgraph, sce);
        
        // <scene>
        std::string scene_name(translate_id(id_name(sce)));
@@@ -39,12 -39,10 +39,12 @@@ struct Scene
  class DocumentExporter
  {
   public:
 -      DocumentExporter(const ExportSettings *export_settings);
 -      int  exportCurrentScene(bContext *C, const EvaluationContext *eval_ctx, Scene *sce);
 +      DocumentExporter(Depsgraph *depsgraph, const ExportSettings *export_settings);
-       int  exportCurrentScene(Scene *sce);
++      int  exportCurrentScene(bContext *C, Scene *sce);
 +
        void exportScenes(const char *filename);
  private:
 +      Depsgraph *depsgraph;
        const ExportSettings *export_settings;
  };
  
@@@ -39,17 -38,17 +39,17 @@@ SceneExporter::SceneExporter(COLLADASW:
  {
  }
  
- void SceneExporter::exportScene(Depsgraph *depsgraph, Scene *sce)
 -void SceneExporter::exportScene(bContext *C, Scene *sce)
++void SceneExporter::exportScene(bContext *C, Depsgraph *depsgraph, Scene *sce)
  {
        // <library_visual_scenes> <visual_scene>
        std::string id_naming = id_name(sce);
        openVisualScene(translate_id(id_naming), id_naming);
-       exportHierarchy(depsgraph, sce);
 -      exportHierarchy(C, sce);
++      exportHierarchy(C, depsgraph, sce);
        closeVisualScene();
        closeLibrary();
  }
  
- void SceneExporter::exportHierarchy(Depsgraph *depsgraph, Scene *sce)
 -void SceneExporter::exportHierarchy(bContext *C, Scene *sce)
++void SceneExporter::exportHierarchy(bContext *C, Depsgraph *depsgraph, Scene *sce)
  {     
        LinkNode *node;
        std::vector<Object *> base_objects;
                Object *ob = base_objects[index];
                if (bc_is_marked(ob)) {
                        bc_remove_mark(ob);
-                       writeNodes(depsgraph, ob, sce);
 -                      writeNodes(C, ob, sce);
++                      writeNodes(C, depsgraph, ob, sce);
                }
        }
  }
  
  
- void SceneExporter::writeNodes(Depsgraph *depsgraph, Object *ob, Scene *sce)
 -void SceneExporter::writeNodes(bContext *C, Object *ob, Scene *sce)
++void SceneExporter::writeNodes(bContext *C, Depsgraph *depsgraph, Object *ob, Scene *sce)
  {
        // Add associated armature first if available
        bool armature_exported = false;
@@@ -96,7 -95,7 +96,7 @@@
                armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
                if (armature_exported && bc_is_marked(ob_arm)) {
                        bc_remove_mark(ob_arm);
-                       writeNodes(depsgraph, ob_arm, sce);
 -                      writeNodes(C, ob_arm, sce);
++                      writeNodes(C, depsgraph, ob_arm, sce);
                        armature_exported = true;
                }
        }
  
        // <instance_controller>
        else if (ob->type == OB_ARMATURE) {
-               arm_exporter->add_armature_bones(depsgraph, ob, sce, this, child_objects);
 -              arm_exporter->add_armature_bones(C, ob, sce, this, child_objects);
++              arm_exporter->add_armature_bones(C, depsgraph, ob, sce, this, child_objects);
        }
  
        // <instance_camera>
        for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
                if (bc_is_marked(*i)) {
                        bc_remove_mark(*i);
-                       writeNodes(depsgraph, *i, sce);
 -                      writeNodes(C, *i, sce);
++                      writeNodes(C, depsgraph, *i, sce);
                }
        }
  
@@@ -96,12 -96,12 +96,12 @@@ class SceneExporter: COLLADASW::Library
  {
  public:
        SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
-       void exportScene(Depsgraph *depsgraph, Scene *sce);
 -      void exportScene(bContext *C, Scene *sce);
++      void exportScene(bContext *C, Depsgraph *depsgraph, Scene *sce);
  
  private:
        friend class ArmatureExporter;
-       void exportHierarchy(struct Depsgraph *depsgraph, Scene *sce);
-       void writeNodes(struct Depsgraph *depsgraph, Object *ob, Scene *sce);
 -      void exportHierarchy(bContext *C, Scene *sce);
 -      void writeNodes(bContext *C, Object *ob, Scene *sce);
++      void exportHierarchy(bContext *C, struct Depsgraph *depsgraph, Scene *sce);
++      void writeNodes(bContext *C, struct Depsgraph *depsgraph, Object *ob, Scene *sce);
        
        ArmatureExporter *arm_exporter;
        const ExportSettings *export_settings;
@@@ -51,7 -48,8 +51,8 @@@ int collada_import(bContext *C, ImportS
        return (imp.import())? 1:0;
  }
  
- int collada_export(Depsgraph *depsgraph,
+ int collada_export(bContext *C,
 -                   EvaluationContext *eval_ctx,
++                   Depsgraph *depsgraph,
                     Scene *sce,
                     ExportSettings *export_settings)
  {
@@@ -79,8 -75,8 +80,8 @@@
                        bc_bubble_sort_by_Object_name(export_settings->export_set);
        }
  
 -      DocumentExporter exporter(export_settings);
 -      int status = exporter.exportCurrentScene(C, eval_ctx, sce);
 +      DocumentExporter exporter(depsgraph, export_settings);
-       int status = exporter.exportCurrentScene(sce);
++      int status = exporter.exportCurrentScene(C, sce);
  
        BLI_linklist_free(export_settings->export_set, NULL);
  
@@@ -51,8 -52,8 +51,9 @@@ struct ViewLayer
  int collada_import(struct bContext *C,
                                   ImportSettings *import_settings);
  
- int collada_export(struct Depsgraph *depsgraph,
 +
 -                   struct EvaluationContext *eval_ctx,
+ int collada_export(struct bContext *C,
++                   struct Depsgraph *depsgraph,
                     struct Scene *sce,
                     ExportSettings *export_settings);
  
  #include "BKE_armature.h"
  #include "BKE_constraint.h"
  #include "BKE_context.h"
 +#include "BKE_layer.h"
  #include "BKE_global.h"
+ #include "BKE_main.h"
  #include "BKE_report.h"
 +#include "BKE_object.h"
  
  #include "RNA_access.h"
  #include "RNA_define.h"
@@@ -140,9 -139,9 +141,9 @@@ void ED_armature_transform(Main *bmain
  
  /* exported for use in editors/object/ */
  /* 0 == do center, 1 == center new, 2 == center cursor */
- void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around)
 -void ED_armature_origin_set(Main *bmain, Scene *scene, Object *ob, float cursor[3], int centermode, int around)
++void ED_armature_origin_set(Main *bmain, Object *ob, float cursor[3], int centermode, int around)
  {
 -      Object *obedit = scene->obedit; // XXX get from context
 +      const bool is_editmode = BKE_object_is_in_editmode(ob);
        EditBone *ebone;
        bArmature *arm = ob->data;
        float cent[3];
        }
  
        /* Turn the list into an armature */
 -      if (obedit == NULL) {
 +      if (is_editmode == false) {
-               ED_armature_from_edit(arm);
+               ED_armature_from_edit(bmain, arm);
                ED_armature_edit_free(arm);
        }
  
@@@ -398,9 -395,9 +398,9 @@@ int join_armature_exec(bContext *C, wmO
        }
        CTX_DATA_END;
  
 -      DAG_relations_tag_update(bmain);  /* because we removed object(s) */
 +      DEG_relations_tag_update(bmain);  /* because we removed object(s) */
  
-       ED_armature_from_edit(arm);
+       ED_armature_from_edit(bmain, arm);
        ED_armature_edit_free(arm);
  
        WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@@ -97,10 -92,9 +97,11 @@@ static void applyarmature_fix_boneparen
  /* set the current pose as the restpose */
  static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
  {
+       Main *bmain = CTX_data_main(C);
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); // must be active object, not edit-object
 +      const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
        bArmature *arm = BKE_armature_from_object(ob);
        bPose *pose;
        bPoseChannel *pchan;
@@@ -39,11 -39,11 +39,12 @@@ struct Base
  struct bContext;
  struct Bone;
  struct bPoseChannel;
 +struct Depsgraph;
  struct IDProperty;
  struct ListBase;
+ struct Main;
  struct MeshDeformModifierData;
 -struct DerivedMesh;
 +struct Mesh;
  struct Object;
  struct ReportList;
  struct Scene;
@@@ -181,11 -163,11 +182,11 @@@ void ED_armature_ebone_from_mat3(EditBo
  void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
  
  void ED_armature_edit_transform_mirror_update(struct Object *obedit);
- void ED_armature_origin_set(struct Object *ob, float cursor[3], int centermode, int around);
 -void ED_armature_origin_set(struct Main *bmain, struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
++void ED_armature_origin_set(struct Main *bmain, struct Object *ob, float cursor[3], int centermode, int around);
  
  void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props);
- void ED_armature_transform_apply(struct Object *ob, float mat[4][4], const bool do_props);
- void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props);
+ void ED_armature_transform_apply(struct Main *bmain, struct Object *ob, float mat[4][4], const bool do_props);
+ void ED_armature_transform(struct Main *bmain, struct bArmature *arm, float mat[4][4], const bool do_props);
  
  #define ARM_GROUPS_NAME     1
  #define ARM_GROUPS_ENVELOPE 2
@@@ -123,13 -116,9 +123,13 @@@ enum 
        EM_FREEDATA         = (1 << 0),
        EM_WAITCURSOR       = (1 << 1),
        EM_IGNORE_LAYER     = (1 << 3),
 +      EM_NO_CONTEXT       = (1 << 4),
  };
 -bool ED_object_editmode_exit_ex(struct Main *bmain, struct Scene *scene, struct Object *obedit, int flag);
 +bool ED_object_editmode_exit_ex(
-         struct Scene *scene, struct Object *obedit, int flag);
++        struct Main *bmain, struct Scene *scene, struct Object *obedit, int flag);
  bool ED_object_editmode_exit(struct bContext *C, int flag);
 +
 +bool ED_object_editmode_enter_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int flag);
  bool ED_object_editmode_enter(struct bContext *C, int flag);
  bool ED_object_editmode_load(struct Main *bmain, struct Object *obedit);
  
@@@ -135,32 -96,9 +135,32 @@@ void    ED_area_newspace(struct bContex
  void    ED_area_prevspace(struct bContext *C, ScrArea *sa);
  void    ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
  int     ED_area_headersize(void);
 +int     ED_area_header_alignment(const ScrArea *area);
 +int     ED_area_global_size_y(const ScrArea *area);
 +bool    ED_area_is_global(const ScrArea *area);
 +int     ED_region_global_size_y(void);
 +void    ED_area_update_region_sizes(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);
 +
 +ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen);
 +ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
 +/**
 + * Iterate over all areas visible in the screen (screen as in everything
 + * visible in the window, not just bScreen).
 + * \note Skips global areas with flag GLOBAL_AREA_IS_HIDDEN.
 + */
 +#define ED_screen_areas_iter(win, screen, area_name)                       \
 +      for (ScrArea *area_name = ED_screen_areas_iter_first(win, screen);     \
 +           area_name != NULL;                                                \
 +           area_name = ED_screen_areas_iter_next(screen, area_name))
 +#define ED_screen_verts_iter(win, screen, vert_name)                       \
 +      for (ScrVert *vert_name = (win)->global_areas.vertbase.first ?         \
 +                                        (win)->global_areas.vertbase.first : \
 +                                        screen->vertbase.first;              \
 +           vert_name != NULL;                                                \
 +           vert_name = (vert_name == (win)->global_areas.vertbase.last) ? (screen)->vertbase.first : vert_name->next)
  
  /* screens */
- void    ED_screens_initialize(struct wmWindowManager *wm);
+ void    ED_screens_initialize(struct Main *bmain, struct wmWindowManager *wm);
  void    ED_screen_draw_edges(struct wmWindow *win);
  void    ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2);
  void    ED_screen_draw_split_preview(struct ScrArea *sa, const int dir, const float fac);
@@@ -205,10 -204,12 +205,12 @@@ static int wm_collada_export_exec(bCont
        if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE;
        if (export_settings.include_children) includeFilter |= OB_REL_CHILDREN_RECURSIVE;
  
-       export_count = collada_export(CTX_data_depsgraph(C),
-               scene,
-               &export_settings
 -
+       export_count = collada_export(
+                          C,
 -                         eval_ctx,
++                         CTX_data_depsgraph(C),
+                          scene,
 -                         &export_settings);
++                         &export_settings
 +      );
  
        if (export_count == 0) {
                BKE_report(op->reports, RPT_WARNING, "No objects selected -- Created empty export file");
@@@ -278,11 -452,11 +278,11 @@@ bool ED_object_editmode_exit_ex(Main *b
  
        if (flag & EM_WAITCURSOR) waitcursor(1);
  
-       if (ED_object_editmode_load_ex(G.main, obedit, freedata) == false) {
+       if (ED_object_editmode_load_ex(bmain, obedit, freedata) == false) {
                /* in rare cases (background mode) its possible active object
                 * is flagged for editmode, without 'obedit' being set [#35489] */
 -              if (UNLIKELY(scene->basact && (scene->basact->object->mode & OB_MODE_EDIT))) {
 -                      scene->basact->object->mode &= ~OB_MODE_EDIT;
 +              if (UNLIKELY(obedit && obedit->mode & OB_MODE_EDIT)) {
 +                      obedit->mode &= ~OB_MODE_EDIT;
                }
                if (flag & EM_WAITCURSOR) waitcursor(0);
                return true;
  
  bool ED_object_editmode_exit(bContext *C, int flag)
  {
+       Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
        Object *obedit = CTX_data_edit_object(C);
-       return ED_object_editmode_exit_ex(scene, obedit, flag);
+       return ED_object_editmode_exit_ex(bmain, scene, obedit, flag);
  }
  
 -bool ED_object_editmode_enter(bContext *C, int flag)
 +bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
  {
 -      Main *bmain = CTX_data_main(C);
 -      Scene *scene = CTX_data_scene(C);
 -      Base *base = NULL;
 -      Object *ob;
 -      ScrArea *sa = CTX_wm_area(C);
 -      View3D *v3d = NULL;
        bool ok = false;
  
 -      if (ID_IS_LINKED(scene)) {
 -              return false;
 -      }
 -
 -      if (sa && sa->spacetype == SPACE_VIEW3D)
 -              v3d = sa->spacedata.first;
 -
 -      if ((flag & EM_IGNORE_LAYER) == 0) {
 -              base = CTX_data_active_base(C); /* active layer checked here for view3d */
 -
 -              if ((base == NULL) ||
 -                  (v3d && (base->lay & v3d->lay) == 0) ||
 -                  (!v3d && (base->lay & scene->lay) == 0))
 -              {
 -                      return false;
 -              }
 -      }
 -      else {
 -              base = scene->basact;
 -      }
 -
 -      if (ELEM(NULL, base, base->object, base->object->data)) {
 +      if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob)) {
                return false;
        }
  
@@@ -461,23 -647,9 +462,23 @@@ static int editmode_toggle_exec(bContex
        }
        else {
                ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR);
-                                       ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA | EM_WAITCURSOR);
 +              if ((obact->mode & mode_flag) == 0) {
 +                      FOREACH_OBJECT_BEGIN(view_layer, ob)
 +                      {
 +                              if ((ob != obact) && (ob->type == obact->type)) {
++                                      ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA | EM_WAITCURSOR);
 +                              }
 +                      }
 +                      FOREACH_OBJECT_END;
 +              }
        }
 +
        ED_space_image_uv_sculpt_update(CTX_wm_manager(C), scene);
  
 +      WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
 +
 +      WM_toolsystem_update_from_context_view3d(C);
 +
        return OPERATOR_FINISHED;
  }
  
@@@ -157,91 -140,30 +157,91 @@@ void ED_object_mode_toggle(bContext *C
  /* Wrapper for operator  */
  void ED_object_mode_set(bContext *C, eObjectMode mode)
  {
 -#if 0
 +      wmWindowManager *wm = CTX_wm_manager(C);
 +      wm->op_undo_depth++;
 +      /* needed so we don't do undo pushes. */
 +      ED_object_mode_generic_enter(C, mode);
 +      wm->op_undo_depth--;
 +}
 +
 +/** \} */
 +
 +/* -------------------------------------------------------------------- */
 +/** \name Generic Mode Enter/Exit
 + *
 + * Supports exiting a mode without it being in the current context.
 + * This could be done for entering modes too if it's needed.
 + *
 + * \{ */
 +
 +bool ED_object_mode_generic_enter(
 +        struct bContext *C, eObjectMode object_mode)
 +{
 +      Object *ob = CTX_data_active_object(C);
 +      if (ob == NULL) {
 +              return (object_mode == OB_MODE_OBJECT);
 +      }
 +      if (ob->mode == object_mode) {
 +              return true;
 +      }
        wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_mode_set", false);
        PointerRNA ptr;
 -
        WM_operator_properties_create_ptr(&ptr, ot);
 -      RNA_enum_set(&ptr, "mode", mode);
 -      RNA_boolean_set(&ptr, "toggle", false);
 -      WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &ptr);
 +      RNA_enum_set(&ptr, "mode", object_mode);
 +      WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
        WM_operator_properties_free(&ptr);
 -#else
 -      Object *ob = CTX_data_active_object(C);
 -      if (ob == NULL) {
 -              return;
 +      return (ob->mode == object_mode);
 +}
 +
 +/**
 + * Use for changing works-paces or changing active object.
 + * Caller can check #OB_MODE_ALL_MODE_DATA to test if this needs to be run.
 + */
 +static bool ed_object_mode_generic_exit_ex(
 +        struct Main *bmain,
 +        struct Depsgraph *depsgraph,
 +        struct Scene *scene, struct Object *ob,
 +        bool only_test)
 +{
 +      BLI_assert((bmain == NULL) == only_test);
 +      if (ob->mode & OB_MODE_EDIT) {
 +              if (BKE_object_is_in_editmode(ob)) {
 +                      if (only_test) {
 +                              return true;
 +                      }
-                       ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA);
++                      ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
 +              }
        }
 -      if (ob->mode == mode) {
 -              /* pass */
 +      else if (ob->mode & OB_MODE_VERTEX_PAINT) {
 +              if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) {
 +                      if (only_test) {
 +                              return true;
 +                      }
 +                      ED_object_vpaintmode_exit_ex(ob);
 +              }
 +      }
 +      else if (ob->mode & OB_MODE_WEIGHT_PAINT) {
 +              if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) {
 +                      if (only_test) {
 +                              return true;
 +                      }
 +                      ED_object_wpaintmode_exit_ex(ob);
 +              }
 +      }
 +      else if (ob->mode & OB_MODE_SCULPT) {
 +              if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) {
 +                      if (only_test) {
 +                              return true;
 +                      }
 +                      ED_object_sculptmode_exit_ex(depsgraph, scene, ob);
 +              }
        }
 -      else if (mode != OB_MODE_OBJECT) {
 -              if (ob && (ob->mode & mode) == 0) {
 -                      /* needed so we don't do undo pushes. */
 -                      wmWindowManager *wm = CTX_wm_manager(C);
 -                      wm->op_undo_depth++;
 -                      ED_object_mode_toggle(C, mode);
 -                      wm->op_undo_depth--;
 +      else if (ob->mode & OB_MODE_POSE) {
 +              if (ob->pose != NULL) {
 +                      if (only_test) {
 +                              return true;
 +                      }
 +                      ED_object_posemode_exit_ex(bmain, ob);
                }
        }
        else {
@@@ -1006,7 -994,7 +1006,7 @@@ static int object_origin_set_exec(bCont
                                        /* Function to recenter armatures in editarmature.c
                                         * Bone + object locations are handled there.
                                         */
-                                       ED_armature_origin_set(ob, cursor, centermode, around);
 -                                      ED_armature_origin_set(bmain, scene, ob, cursor, centermode, around);
++                                      ED_armature_origin_set(bmain, ob, cursor, centermode, around);
  
                                        tot_change++;
                                        arm->id.tag |= LIB_TAG_DOIT;
@@@ -337,22 -457,26 +337,22 @@@ ScrArea *area_split(bScreen *sc, ScrAre
        return newa;
  }
  
 -/* empty screen, with 1 dummy area without spacedata */
 -/* uses window size */
 -bScreen *ED_screen_add(Main *bmain, wmWindow *win, Scene *scene, const char *name)
 +/**
 + * Empty screen, with 1 dummy area without spacedata. Uses window size.
 + */
- bScreen *screen_add(const char *name, const rcti *rect)
++bScreen *screen_add(Main *bmain, const char *name, const rcti *rect)
  {
 -      const int winsize_x = WM_window_pixels_x(win);
 -      const int winsize_y = WM_window_pixels_y(win);
 -
        bScreen *sc;
        ScrVert *sv1, *sv2, *sv3, *sv4;
  
-       sc = BKE_libblock_alloc(G.main, ID_SCR, name, 0);
+       sc = BKE_libblock_alloc(bmain, ID_SCR, name, 0);
 -      sc->scene = scene;
        sc->do_refresh = true;
        sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
 -      sc->winid = win->winid;
  
 -      sv1 = screen_addvert(sc, 0, 0);
 -      sv2 = screen_addvert(sc, 0, winsize_y - 1);
 -      sv3 = screen_addvert(sc, winsize_x - 1, winsize_y - 1);
 -      sv4 = screen_addvert(sc, winsize_x - 1, 0);
 +      sv1 = screen_addvert(sc, rect->xmin,     rect->ymin);
 +      sv2 = screen_addvert(sc, rect->xmin,     rect->ymax - 1);
 +      sv3 = screen_addvert(sc, rect->xmax - 1, rect->ymax - 1);
 +      sv4 = screen_addvert(sc, rect->xmax - 1, rect->ymin);
  
        screen_addedge(sc, sv1, sv2);
        screen_addedge(sc, sv2, sv3);
@@@ -832,7 -951,7 +832,7 @@@ void ED_screen_refresh(wmWindowManager 
  }
  
  /* file read, set all screens, ... */
- void ED_screens_initialize(wmWindowManager *wm)
 -void ED_screens_initialize(Main *bmain, wmWindowManager *wm)
++void ED_screens_initialize(Main *UNUSED(bmain), wmWindowManager *wm)
  {
        wmWindow *win;
  
@@@ -44,15 -43,10 +44,15 @@@ struct Main
  /* area.c */
  void        ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free);
  void        ED_area_data_swap(ScrArea *sa1, ScrArea *sa2);
 -void          region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
 +void        screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area);
 +void        region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
  
  /* screen_edit.c */
- bScreen    *screen_add(const char *name, const rcti *rect);
 -ScrEdge    *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
++bScreen    *screen_add(struct Main *bmain, const char *name, const rcti *rect);
 +void        screen_data_copy(bScreen *to, bScreen *from);
 +void        screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new);
 +void        screen_change_update(struct bContext *C, wmWindow *win, bScreen *sc);
 +bScreen    *screen_change_prepare(bScreen *screen_old, bScreen *screen_new, struct Main *bmain, struct bContext *C, wmWindow *win);
  ScrArea    *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge);
  int         screen_area_join(struct bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2);
  int         area_getorientation(ScrArea *sa, ScrArea *sb);
index 6285f03,0000000..4cb88b7
mode 100644,000000..100644
--- /dev/null
@@@ -1,197 -1,0 +1,197 @@@
-       screen = screen_add(name, &screen_rect);
 +/*
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +
 +/** \file blender/editors/screen/workspace_layout_edit.c
 + *  \ingroup edscr
 + */
 +
 +#include <stdlib.h>
 +
 +#include "BLI_utildefines.h"
 +#include "BLI_listbase.h"
 +
 +#include "DNA_screen_types.h"
 +#include "DNA_workspace_types.h"
 +
 +#include "BKE_context.h"
 +#include "BKE_global.h"
 +#include "BKE_main.h"
 +#include "BKE_screen.h"
 +#include "BKE_workspace.h"
 +
 +#include "WM_api.h"
 +
 +#include "ED_screen.h"
 +
 +#include "screen_intern.h"
 +
 +/**
 + * Empty screen, with 1 dummy area without spacedata. Uses window size.
 + */
 +WorkSpaceLayout *ED_workspace_layout_add(
 +        WorkSpace *workspace,
 +        wmWindow *win,
 +        const char *name)
 +{
 +      bScreen *screen;
 +      rcti screen_rect;
 +
 +      WM_window_screen_rect_calc(win, &screen_rect);
++      screen = screen_add(G.main, name, &screen_rect);
 +
 +      return BKE_workspace_layout_add(workspace, screen, name);
 +}
 +
 +WorkSpaceLayout *ED_workspace_layout_duplicate(
 +        WorkSpace *workspace, const WorkSpaceLayout *layout_old,
 +        wmWindow *win)
 +{
 +      bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old);
 +      const char *name = BKE_workspace_layout_name_get(layout_old);
 +      bScreen *screen_new;
 +      WorkSpaceLayout *layout_new;
 +
 +      if (BKE_screen_is_fullscreen_area(screen_old)) {
 +              return NULL; /* XXX handle this case! */
 +      }
 +
 +      layout_new = ED_workspace_layout_add(workspace, win, name);
 +      screen_new = BKE_workspace_layout_screen_get(layout_new);
 +      screen_data_copy(screen_new, screen_old);
 +
 +      return layout_new;
 +}
 +
 +static bool workspace_layout_delete_doit(
 +        WorkSpace *workspace, WorkSpaceLayout *layout_old, WorkSpaceLayout *layout_new,
 +        bContext *C)
 +{
 +      Main *bmain = CTX_data_main(C);
 +      wmWindow *win = CTX_wm_window(C);
 +      bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
 +
 +      ED_screen_change(C, screen_new);
 +
 +      if (BKE_workspace_active_layout_get(win->workspace_hook) != layout_old) {
 +              BKE_workspace_layout_remove(bmain, workspace, layout_old);
 +              return true;
 +      }
 +
 +      return false;
 +}
 +
 +bool workspace_layout_set_poll(const WorkSpaceLayout *layout)
 +{
 +      const bScreen *screen = BKE_workspace_layout_screen_get(layout);
 +
 +      return ((BKE_screen_is_used(screen) == false) &&
 +              /* in typical usage temp screens should have a nonzero winid
 +               * (all temp screens should be used, or closed & freed). */
 +              (screen->temp == false) &&
 +              (BKE_screen_is_fullscreen_area(screen) == false) &&
 +              (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT)));
 +}
 +
 +static WorkSpaceLayout *workspace_layout_delete_find_new(const WorkSpaceLayout *layout_old)
 +{
 +      for (WorkSpaceLayout *layout_new = layout_old->prev; layout_new; layout_new = layout_new->next) {
 +              if (workspace_layout_set_poll(layout_new)) {
 +                      return layout_new;
 +              }
 +      }
 +
 +      for (WorkSpaceLayout *layout_new = layout_old->next; layout_new; layout_new = layout_new->next) {
 +              if (workspace_layout_set_poll(layout_new)) {
 +                      return layout_new;
 +              }
 +      }
 +
 +      return NULL;
 +}
 +
 +/**
 + * \warning Only call outside of area/region loops!
 + * \return true if succeeded.
 + */
 +bool ED_workspace_layout_delete(
 +        WorkSpace *workspace, WorkSpaceLayout *layout_old,
 +        bContext *C)
 +{
 +      const bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old);
 +      WorkSpaceLayout *layout_new;
 +
 +      BLI_assert(BLI_findindex(BKE_workspace_layouts_get(workspace), layout_old) != -1);
 +
 +      /* don't allow deleting temp fullscreens for now */
 +      if (BKE_screen_is_fullscreen_area(screen_old)) {
 +              return false;
 +      }
 +
 +      /* A layout/screen can only be in use by one window at a time, so as
 +       * long as we are able to find a layout/screen that is unused, we
 +       * can safely assume ours is not in use anywhere an delete it. */
 +
 +      layout_new = workspace_layout_delete_find_new(layout_old);
 +
 +      if (layout_new) {
 +              return workspace_layout_delete_doit(workspace, layout_old, layout_new, C);
 +      }
 +
 +      return false;
 +}
 +
 +static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
 +{
 +      /* return false to stop iterator when we have found a layout to activate */
 +      return !workspace_layout_set_poll(layout);
 +}
 +
 +bool ED_workspace_layout_cycle(
 +        WorkSpace *workspace, const short direction, bContext *C)
 +{
 +      wmWindow *win = CTX_wm_window(C);
 +      WorkSpaceLayout *old_layout = BKE_workspace_active_layout_get(win->workspace_hook);
 +      WorkSpaceLayout *new_layout;
 +      const bScreen *old_screen = BKE_workspace_layout_screen_get(old_layout);
 +      ScrArea *sa = CTX_wm_area(C);
 +
 +      if (old_screen->temp || (sa && sa->full && sa->full->temp)) {
 +              return false;
 +      }
 +
 +      BLI_assert(ELEM(direction, 1, -1));
 +      new_layout = BKE_workspace_layout_iter_circular(workspace, old_layout, workspace_layout_cycle_iter_cb,
 +                                                      NULL, (direction == -1) ? true : false);
 +
 +      if (new_layout && (old_layout != new_layout)) {
 +              bScreen *new_screen = BKE_workspace_layout_screen_get(new_layout);
 +
 +              if (sa && sa->full) {
 +                      /* return to previous state before switching screens */
 +                      ED_screen_full_restore(C, sa); /* may free screen of old_layout */
 +              }
 +
 +              ED_screen_change(C, new_screen);
 +
 +              return true;
 +      }
 +
 +      return false;
 +}
  #include "BLI_utildefines.h"
  #include "BLI_listbase.h"
  
 +#include "BKE_armature.h"
 +#include "BKE_collection.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
 +#include "BKE_layer.h"
++#include "BKE_main.h"
  #include "BKE_object.h"
  #include "BKE_scene.h"
  #include "BKE_sequencer.h"
  
  #include "outliner_intern.h"
  
 -/* ****************************************************** */
 -/* Outliner Selection (gray-blue highlight for rows) */
 +static void do_outliner_activate_obdata(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base)
 +{
++      Main *bmain = CTX_data_main(C);
 +      Object *obact = OBACT(view_layer);
 +      bool use_all = false;
 +
 +      if (obact == NULL) {
 +              ED_object_base_activate(C, base);
 +              WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 +              obact = base->object;
 +              use_all = true;
 +      }
 +      else if (obact->data == base->object->data) {
 +              use_all = true;
 +      }
  
 -static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selecting)
 +      if (use_all) {
 +              WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
 +      }
 +      else {
 +              Object *ob = base->object;
 +              if (ob->type == obact->type) {
 +                      bool ok;
 +                      if (BKE_object_is_in_editmode(ob)) {
-                               ok = ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA | EM_WAITCURSOR);
++                              ok = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA | EM_WAITCURSOR);
 +                      }
 +                      else {
 +                              ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT);
 +                      }
 +                      if (ok) {
 +                              ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT);
 +                              WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 +                      }
 +              }
 +      }
 +}
 +
 +static void do_outliner_activate_pose(bContext *C, ViewLayer *view_layer, Base *base)
  {
 -      TreeElement *te;
 -      TreeStoreElem *tselem;
 -      bool changed = false;
 -
 -      for (te = lb->first; te && *index >= 0; te = te->next, (*index)--) {
 -              tselem = TREESTORE(te);
 -
 -              /* if we've encountered the right item, set its 'Outliner' selection status */
 -              if (*index == 0) {
 -                      /* this should be the last one, so no need to do anything with index */
 -                      if ((te->flag & TE_ICONROW) == 0) {
 -                              /* -1 value means toggle testing for now... */
 -                              if (*selecting == -1) {
 -                                      if (tselem->flag & TSE_SELECTED)
 -                                              *selecting = 0;
 -                                      else
 -                                              *selecting = 1;
 -                              }
 +      Object *obact = OBACT(view_layer);
 +      bool use_all = false;
 +
 +      if (obact == NULL) {
 +              ED_object_base_activate(C, base);
 +              Scene *scene = CTX_data_scene(C);
 +              WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 +              obact = base->object;
 +              use_all = true;
 +      }
 +      else if (obact->data == base->object->data) {
 +              use_all = true;
 +      }
  
 -                              /* set selection */
 -                              if (*selecting)
 -                                      tselem->flag |= TSE_SELECTED;
 -                              else
 -                                      tselem->flag &= ~TSE_SELECTED;
 +      if (use_all) {
 +              WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
 +      }
 +      else {
 +              Object *ob = base->object;
 +              if (ob->type == obact->type) {
 +                      struct Main *bmain = CTX_data_main(C);
 +                      bool ok = false;
 +                      if (ob->mode & OB_MODE_POSE) {
 +                              ok = ED_object_posemode_exit_ex(bmain, ob);
 +                      }
 +                      else {
 +                              ok = ED_object_posemode_enter_ex(bmain, ob);
 +                      }
 +                      if (ok) {
 +                              ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT);
  
 -                              changed |= true;
 +                              Scene *scene = CTX_data_scene(C);
 +                              WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
 +                              WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
                        }
                }
 -              else if (TSELEM_OPEN(tselem, soops)) {
 -                      /* Only try selecting sub-elements if we haven't hit the right element yet
 -                       *
 -                       * Hack warning:
 -                       *  Index must be reduced before supplying it to the sub-tree to try to do
 -                       *  selection, however, we need to increment it again for the next loop to
 -                       *  function correctly
 -                       */
 -                      (*index)--;
 -                      changed |= outliner_select(soops, &te->subtree, index, selecting);
 -                      (*index)++;
 -              }
        }
 -
 -      return changed;
  }
  
  /* ****************************************************** */
@@@ -417,15 -405,11 +418,15 @@@ void WM_check(bContext *C
                wm_window_ghostwindows_ensure(wm);
        }
  
 +      if (wm->message_bus == NULL) {
 +              wm->message_bus = WM_msgbus_create();
 +      }
 +
        /* case: fileread */
        /* note: this runs in bg mode to set the screen context cb */
 -      if ((wm->initialized & WM_INIT_WINDOW) == 0) {
 +      if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
-               ED_screens_initialize(wm);
+               ED_screens_initialize(bmain, wm);
 -              wm->initialized |= WM_INIT_WINDOW;
 +              wm->initialized |= WM_WINDOW_IS_INITIALIZED;
        }
  }
  
@@@ -600,7 -590,7 +603,7 @@@ bool WM_file_read(bContext *C, const ch
                }
  
                /* match the read WM with current WM */
-               wm_window_match_do(C, &wmbase, &G.main->wm, &G.main->wm);
 -              wm_window_match_do(bmain, C, &wmbase);
++              wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
                WM_check(C); /* opens window(s), checks keymaps */
  
                if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {