diff options
Diffstat (limited to 'source/blender/blenkernel/intern/blender.c')
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 94 |
1 files changed, 74 insertions, 20 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index adfe43cb2a3..b6ea780576e 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -61,6 +61,7 @@ #include "IMB_imbuf.h" #include "IMB_moviecache.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_bpath.h" #include "BKE_brush.h" @@ -145,10 +146,6 @@ void initglobals(void) else BLI_snprintf(versionstr, sizeof(versionstr), "v%d.%02d", BLENDER_VERSION / 100, BLENDER_VERSION % 100); -#ifdef _WIN32 - G.windowstate = 0; -#endif - #ifndef WITH_PYTHON_SECURITY /* default */ G.f |= G_SCRIPT_AUTOEXEC; #else @@ -188,6 +185,17 @@ static void clean_paths(Main *main) } } +static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene) +{ + wmWindow *win; + for (win = wm->windows.first; win; win = win->next) { + if (win->screen->scene == scene) { + return true; + } + } + return false; +} + /* context matching */ /* handle no-ui case */ @@ -231,6 +239,20 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* no load screens? */ if (mode != LOAD_UI) { + /* Logic for 'track_undo_scene' is to keep using the scene which the active screen has, + * as long as the scene associated with the undo operation is visible in one of the open windows. + * + * - 'curscreen->scene' - scene the user is currently looking at. + * - 'bfd->curscene' - scene undo-step was created in. + * + * This means users can have 2+ windows open and undo in both without screens switching. + * But if they close one of the screens, + * undo will ensure that the scene being operated on will be activated + * (otherwise we'd be undoing on an off-screen scene which isn't acceptable). + * see: T43424 + */ + bool track_undo_scene; + /* comes from readfile.c */ SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); @@ -240,15 +262,36 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath curscreen = CTX_wm_screen(C); /* but use new Scene pointer */ curscene = bfd->curscene; + + track_undo_scene = (mode == LOAD_UNDO && curscreen && bfd->main->wm.first); + if (curscene == NULL) curscene = bfd->main->scene.first; /* empty file, we add a scene to make Blender work */ if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); - - /* and we enforce curscene to be in current screen */ - if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ + + 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; + } + } /* clear_global will free G.main, here we can still restore pointers */ blo_lib_link_screen_restore(bfd->main, curscreen, curscene); + curscene = curscreen->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; + } + } } /* free G.main Main database */ @@ -270,6 +313,17 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath BKE_userdef_free(); U = *bfd->user; + + /* Security issue: any blend file could include a USER block. + * + * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE, + * to load the preferences defined in the users home dir. + * + * This means we will never accidentally (or maliciously) + * enable scripts auto-execution by loading a '.blend' file. + */ + U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; + MEM_freeN(bfd->user); } @@ -279,8 +333,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath CTX_data_scene_set(C, curscene); } else { - G.winpos = bfd->winpos; - G.displaymode = bfd->displaymode; G.fileflags = bfd->fileflags; CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); @@ -493,10 +545,11 @@ bool BKE_read_file_from_memory( BLO_update_defaults_startup_blend(bfd->main); setup_app_data(C, bfd, "<memory2>"); } - else + else { BKE_reports_prepend(reports, "Loading failed: "); + } - return (bfd ? 1 : 0); + return (bfd != NULL); } /* memfile is the undo buffer */ @@ -516,10 +569,11 @@ bool BKE_read_file_from_memfile( setup_app_data(C, bfd, "<memory1>"); } - else + else { BKE_reports_prepend(reports, "Loading failed: "); + } - return (bfd ? 1 : 0); + return (bfd != NULL); } /* only read the userdef from a .blend */ @@ -565,7 +619,7 @@ int BKE_write_file_userdef(const char *filepath, ReportList *reports) static void (*blender_test_break_cb)(void) = NULL; -void set_blender_test_break_cb(void (*func)(void) ) +void set_blender_test_break_cb(void (*func)(void)) { blender_test_break_cb = func; } @@ -687,7 +741,7 @@ void BKE_write_undo(bContext *C, const char *name) counter = counter % U.undosteps; BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); - BLI_make_file_string("/", filepath, BLI_temp_dir_session(), numstr); + BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr); /* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); @@ -834,13 +888,13 @@ bool BKE_undo_save_file(const char *filename) int file, oflags; if ((U.uiflag & USER_GLOBALUNDO) == 0) { - return 0; + return false; } uel = curundo; if (uel == NULL) { fprintf(stderr, "No undo buffer to save recovery file\n"); - return 0; + return false; } /* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK, @@ -862,7 +916,7 @@ bool BKE_undo_save_file(const char *filename) if (file == -1) { fprintf(stderr, "Unable to save '%s': %s\n", filename, errno ? strerror(errno) : "Unknown error opening file"); - return 0; + return false; } for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) { @@ -876,9 +930,9 @@ bool BKE_undo_save_file(const char *filename) if (chunk) { fprintf(stderr, "Unable to save '%s': %s\n", filename, errno ? strerror(errno) : "Unknown error writing file"); - return 0; + return false; } - return 1; + return true; } /* sets curscene */ |