Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Sat, 12 Aug 2017 15:14:55 +0000 (01:14 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 12 Aug 2017 15:14:55 +0000 (01:14 +1000)
1  2 
source/blender/blenkernel/intern/blendfile.c
source/blender/windowmanager/intern/wm_init_exit.c

index 09760fcc4cbf7a81103b4b6f13e6e72823f007b2,980df05aca2208e7108cac91583baabd745035e1..e1350aa8a46aa2e63235d707a4bb92d2abc3a4d9
@@@ -32,7 -32,6 +32,7 @@@
  
  #include "DNA_scene_types.h"
  #include "DNA_screen_types.h"
 +#include "DNA_workspace_types.h"
  
  #include "BLI_listbase.h"
  #include "BLI_string.h"
  #include "BKE_context.h"
  #include "BKE_global.h"
  #include "BKE_ipo.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_main.h"
  #include "BKE_report.h"
  #include "BKE_scene.h"
  #include "BKE_screen.h"
 +#include "BKE_workspace.h"
  
  #include "BLO_readfile.h"
  #include "BLO_writefile.h"
@@@ -96,7 -93,7 +96,7 @@@ static bool wm_scene_is_visible(wmWindo
  {
        wmWindow *win;
        for (win = wm->windows.first; win; win = win->next) {
 -              if (win->screen->scene == scene) {
 +              if (win->scene == scene) {
                        return true;
                }
        }
@@@ -117,6 -114,7 +117,7 @@@ static void setup_app_data
          const char *filepath, ReportList *reports)
  {
        Scene *curscene = NULL;
+       const bool is_startup = (bfd->filename[0] == '\0');
        const bool recover = (G.fileflags & G_FILE_RECOVER) != 0;
        enum {
                LOAD_UI = 1,
        else if (BLI_listbase_is_empty(&bfd->main->screen)) {
                mode = LOAD_UNDO;
        }
-       else if (G.fileflags & G_FILE_NO_UI) {
+       else if ((G.fileflags & G_FILE_NO_UI) && (is_startup == false)) {
                mode = LOAD_UI_OFF;
        }
        else {
                 * (otherwise we'd be undoing on an off-screen scene which isn't acceptable).
                 * see: T43424
                 */
 +              wmWindow *win;
                bScreen *curscreen = NULL;
 +              SceneLayer *cur_render_layer;
                bool track_undo_scene;
  
                /* comes from readfile.c */
                SWAP(ListBase, G.main->wm, bfd->main->wm);
 +              SWAP(ListBase, G.main->workspaces, bfd->main->workspaces);
                SWAP(ListBase, G.main->screen, bfd->main->screen);
  
 -              /* we re-use current screen */
 +              /* we re-use current window and screen */
 +              win = CTX_wm_window(C);
                curscreen = CTX_wm_screen(C);
 -              /* but use new Scene pointer */
 +              /* but use Scene pointer from new file */
                curscene = bfd->curscene;
 +              cur_render_layer = bfd->cur_render_layer;
  
                track_undo_scene = (mode == LOAD_UNDO && curscreen && curscene && bfd->main->wm.first);
  
                if (curscene == NULL) {
                        curscene = BKE_scene_add(bfd->main, "Empty");
                }
 +              if (cur_render_layer == NULL) {
 +                      /* fallback to scene layer */
 +                      cur_render_layer = BKE_scene_layer_from_scene_get(curscene);
 +              }
  
                if (track_undo_scene) {
                        /* keep the old (free'd) scene, let 'blo_lib_link_screen_restore'
                         * replace it with 'curscene' if its needed */
                }
 -              else {
 -                      /* and we enforce curscene to be in current screen */
 -                      if (curscreen) {
 -                              /* can run in bgmode */
 -                              curscreen->scene = curscene;
 -                      }
 +              /* and we enforce curscene to be in current screen */
 +              else if (win) { /* can run in bgmode */
 +                      win->scene = curscene;
                }
  
                /* BKE_blender_globals_clear will free G.main, here we can still restore pointers */
 -              blo_lib_link_screen_restore(bfd->main, curscreen, curscene);
 -              /* curscreen might not be set when loading without ui (see T44217) so only re-assign if available */
 -              if (curscreen) {
 -                      curscene = curscreen->scene;
 +              blo_lib_link_restore(bfd->main, CTX_wm_manager(C), curscene, cur_render_layer);
 +              if (win) {
 +                      curscene = win->scene;
                }
  
                if (track_undo_scene) {
                        wmWindowManager *wm = bfd->main->wm.first;
                        if (wm_scene_is_visible(wm, bfd->curscene) == false) {
                                curscene = bfd->curscene;
 -                              curscreen->scene = curscene;
 -                              BKE_screen_view3d_scene_sync(curscreen);
 +                              BKE_screen_view3d_scene_sync(curscreen, curscene);
                        }
                }
 +
 +              /* We need to tag this here because events may be handled immediately after.
 +               * only the current screen is important because we wont have to handle
 +               * events from multiple screens at once.*/
 +              {
 +                      BKE_screen_manipulator_tag_refresh(curscreen);
 +              }
        }
  
        /* free G.main Main database */
                CTX_data_scene_set(C, curscene);
        }
        else {
-               G.fileflags = bfd->fileflags;
+               /* Keep state from preferences. */
+               const int fileflags_skip = G_FILE_FLAGS_RUNTIME;
+               G.fileflags = (G.fileflags & fileflags_skip) | (bfd->fileflags & ~fileflags_skip);
                CTX_wm_manager_set(C, G.main->wm.first);
                CTX_wm_screen_set(C, bfd->curscreen);
                CTX_data_scene_set(C, bfd->curscene);
  
        /* this can happen when active scene was lib-linked, and doesn't exist anymore */
        if (CTX_data_scene(C) == NULL) {
 +              wmWindow *win = CTX_wm_window(C);
 +
                /* in case we don't even have a local scene, add one */
                if (!G.main->scene.first)
                        BKE_scene_add(G.main, "Empty");
  
                CTX_data_scene_set(C, G.main->scene.first);
 -              CTX_wm_screen(C)->scene = CTX_data_scene(C);
 +              win->scene = CTX_data_scene(C);
                curscene = CTX_data_scene(C);
        }
  
                wmWindowManager *wm = G.main->wm.first;
  
                if (wm) {
 -                      wmWindow *win;
 -
 -                      for (win = wm->windows.first; win; win = win->next) {
 -                              if (win->screen && win->screen->scene) /* zealous check... */
 -                                      if (win->screen->scene != curscene)
 -                                              BKE_scene_set_background(G.main, win->screen->scene);
 +                      for (wmWindow *win = wm->windows.first; win; win = win->next) {
 +                              if (win->scene && win->scene != curscene) {
 +                                      BKE_scene_set_background(G.main, win->scene);
 +                              }
                        }
                }
        }
 +
 +      /* Setting scene might require having a dependency graph, with copy on write
 +       * we need to make sure we ensure scene has correct color management before
 +       * constructing dependency graph.
 +       */
 +      if (mode != LOAD_UNDO) {
 +              IMB_colormanagement_check_file_config(G.main);
 +      }
 +
        BKE_scene_set_background(G.main, curscene);
  
        if (mode != LOAD_UNDO) {
 +              /* TODO(sergey): Can this be also move above? */
                RE_FreeAllPersistentData();
 -              IMB_colormanagement_check_file_config(G.main);
        }
  
        MEM_freeN(bfd);
@@@ -532,49 -512,6 +535,49 @@@ int BKE_blendfile_userdef_write(const c
        return retval;
  }
  
 +WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath, ReportList *reports)
 +{
 +      BlendFileData *bfd;
 +      WorkspaceConfigFileData *workspace_config = NULL;
 +
 +      bfd = BLO_read_from_file(filepath, reports, BLO_READ_SKIP_USERDEF);
 +      if (bfd) {
 +              workspace_config = MEM_mallocN(sizeof(*workspace_config), __func__);
 +              workspace_config->main = bfd->main;
 +              workspace_config->workspaces = bfd->main->workspaces;
 +
 +              MEM_freeN(bfd);
 +      }
 +
 +      return workspace_config;
 +}
 +
 +bool BKE_blendfile_workspace_config_write(Main *bmain, const char *filepath, ReportList *reports)
 +{
 +      int fileflags = G.fileflags & ~(G_FILE_NO_UI | G_FILE_AUTOPLAY | G_FILE_HISTORY);
 +      bool retval = false;
 +
 +      BKE_blendfile_write_partial_begin(bmain);
 +
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              BKE_blendfile_write_partial_tag_ID(&workspace->id, true);
 +      }
 +
 +      if (BKE_blendfile_write_partial(bmain, filepath, fileflags, reports)) {
 +              retval = true;
 +      }
 +
 +      BKE_blendfile_write_partial_end(bmain);
 +
 +      return retval;
 +}
 +
 +void BKE_blendfile_workspace_config_data_free(WorkspaceConfigFileData *workspace_config)
 +{
 +      BKE_main_free(workspace_config->main);
 +      MEM_freeN(workspace_config);
 +}
 +
  /** \} */
  
  
index 5d90f0eb3e6627e164989aeaa3fd803bbaef0851,e73ec2b081afb1d54a6561e7a34a8e889646a037..8346535cd6a9a0d4d307a58adec57630719d5483
  #include "GPU_draw.h"
  #include "GPU_init_exit.h"
  
 -#include "BKE_depsgraph.h"
  #include "BKE_sound.h"
  #include "COM_compositor.h"
  
 +#include "DEG_depsgraph.h"
 +
  #ifdef WITH_OPENSUBDIV
  #  include "BKE_subsurf.h"
  #endif
@@@ -165,21 -164,17 +165,21 @@@ void WM_init(bContext *C, int argc, con
        wm_operatortype_init();
        WM_menutype_init();
        WM_uilisttype_init();
 +      wm_manipulatortype_init();
 +      wm_manipulatorgrouptype_init();
  
        BKE_undo_callback_wm_kill_jobs_set(wm_undo_kill_callback);
  
        BKE_library_callback_free_window_manager_set(wm_close_and_free);   /* library.c */
        BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference);   /* library.c */
 +      BKE_region_callback_free_manipulatormap_set(wm_manipulatormap_remove); /* screen.c */
 +      BKE_region_callback_refresh_tag_manipulatormap_set(WM_manipulatormap_tag_refresh);
        BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference);   /* library.c */
        BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */
        BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */
 -      DAG_editors_update_cb(ED_render_id_flush_update,
 -                            ED_render_scene_update,
 -                            ED_render_scene_update_pre); /* depsgraph.c */
 +      DEG_editors_set_update_cb(ED_render_id_flush_update,
 +                                ED_render_scene_update,
 +                                ED_render_scene_update_pre);
        
        ED_spacetypes_init();   /* editors/space_api/spacetype.c */
        
        BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
        BLT_lang_init();
  
-       /* Enforce loading the UI for the initial homefile */
-       G.fileflags &= ~G_FILE_NO_UI;
        /* reports cant be initialized before the wm,
         * but keep before file reading, since that may report errors */
        wm_init_reports(C);
@@@ -481,7 -473,7 +478,7 @@@ void WM_exit_ext(bContext *C, const boo
                        CTX_wm_window_set(C, win);  /* needed by operator close callbacks */
                        WM_event_remove_handlers(C, &win->handlers);
                        WM_event_remove_handlers(C, &win->modalhandlers);
 -                      ED_screen_exit(C, win, win->screen);
 +                      ED_screen_exit(C, win, WM_window_get_active_screen(win));
                }
        }
  
        ED_gpencil_strokes_copybuf_free();
        BKE_node_clipboard_clear();
  
 +      /* free manipulator-maps after freeing blender, so no deleted data get accessed during cleaning up of areas */
 +      wm_manipulatormaptypes_free();
 +      wm_manipulatorgrouptype_free();
 +      wm_manipulatortype_free();
 +
        BLF_exit();
  
  #ifdef WITH_INTERNATIONAL