Fix saving a quit.blend on exit when a file failed to load

When a file passed in from the command line failed to load,
blender would exit & save the quit.blend.

Resolve by adding a `do_user_exit_actions` to WM_exit_ex which is
false in backgrounds mode or when an error has occurred.
This commit is contained in:
Campbell Barton 2023-05-30 13:24:18 +10:00
parent 9a4fb83fdb
commit c803ddab29
4 changed files with 24 additions and 7 deletions

View file

@ -22,7 +22,7 @@ static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyOb
/* close down enough of blender at least not to crash */
struct bContext *C = BPY_context_get();
WM_exit_ex(C, false);
WM_exit_ex(C, false, false);
Py_RETURN_NONE;
}

View file

@ -100,9 +100,17 @@ void WM_init_input_devices(void);
*/
void WM_init(struct bContext *C, int argc, const char **argv);
/**
* \param do_python: Free all data associated with Blender's Python integration.
* Also exit the Python interpreter (unless `WITH_PYTHON_MODULE` is enabled).
* \param do_user_exit_actions: When enabled perform actions associated with a user
* having been using Blender then exiting. Actions such as writing the auto-save
* and writing any changes to preferences.
* Set to false in background mode or when exiting because of failed command line argument parsing.
* In general automated actions where the user isn't making changes should pass in false too.
*
* \note doesn't run exit() call #WM_exit() for that.
*/
void WM_exit_ex(struct bContext *C, bool do_python);
void WM_exit_ex(struct bContext *C, bool do_python, bool do_user_exit_actions);
/**
* \brief Main exit function to close Blender ordinarily.
@ -111,6 +119,8 @@ void WM_exit_ex(struct bContext *C, bool do_python);
*
* \param exit_code: Passed to #exit, typically #EXIT_SUCCESS or #EXIT_FAILURE should be used.
* With failure being used for an early exit when parsing command line arguments fails.
* Note that any exit-code besides #EXIT_SUCCESS calls #WM_exit_ex with its `do_user_exit_actions`
* argument set to false.
*/
void WM_exit(struct bContext *C, int exit_code) ATTR_NORETURN;

View file

@ -472,15 +472,21 @@ void wm_exit_schedule_delayed(const bContext *C)
void UV_clipboard_free();
void WM_exit_ex(bContext *C, const bool do_python)
void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actions)
{
wmWindowManager *wm = C ? CTX_wm_manager(C) : nullptr;
/* While nothing technically prevents saving user data in background mode,
* don't do this as not typically useful and more likely to cause problems
* if automated scripts happen to write changes to the preferences for e.g.
* Saving #BLENDER_QUIT_FILE is also not likely to be desired either. */
BLI_assert(G.background ? (do_user_exit_actions == false) : true);
/* first wrap up running stuff, we assume only the active WM is running */
/* modal handlers are on window level freed, others too? */
/* NOTE: same code copied in `wm_files.cc`. */
if (C && wm) {
if (!G.background) {
if (do_user_exit_actions) {
struct MemFile *undo_memfile = wm->undo_stack ?
ED_undosys_stack_memfile_get_active(wm->undo_stack) :
nullptr;
@ -514,7 +520,7 @@ void WM_exit_ex(bContext *C, const bool do_python)
ED_screen_exit(C, win, WM_window_get_active_screen(win));
}
if (!G.background) {
if (do_user_exit_actions) {
if ((U.pref_flag & USER_PREF_FLAG_SAVE) && ((G.f & G_FLAG_USERPREF_NO_SAVE_ON_EXIT) == 0)) {
if (U.runtime.is_dirty) {
BKE_blendfile_userdef_write_all(nullptr);
@ -692,7 +698,8 @@ void WM_exit_ex(bContext *C, const bool do_python)
void WM_exit(bContext *C, const int exit_code)
{
WM_exit_ex(C, true);
const bool do_user_exit_actions = G.background ? (exit_code == EXIT_SUCCESS) : false;
WM_exit_ex(C, true, do_user_exit_actions);
printf("\nBlender quit\n");

View file

@ -594,7 +594,7 @@ int main(int argc,
#ifdef WITH_PYTHON_MODULE
void main_python_exit(void)
{
WM_exit_ex((bContext *)evil_C, true);
WM_exit_ex((bContext *)evil_C, true, false);
evil_C = NULL;
}
#endif