diff --git a/source/blender/windowmanager/WM_api.hh b/source/blender/windowmanager/WM_api.hh index bc7786a8779..c810ea65725 100644 --- a/source/blender/windowmanager/WM_api.hh +++ b/source/blender/windowmanager/WM_api.hh @@ -423,9 +423,20 @@ void WM_window_decoration_style_apply(const wmWindow *win, const bScreen *screen /* `wm_files.cc`. */ void WM_file_autoexec_init(const char *filepath); -bool WM_file_read(bContext *C, const char *filepath, ReportList *reports); +/** + * \param use_scripts_autoexec_check: When true, script auto-execution checks excluded directories. + * Note that this is passed in as an argument because `filepath` may reference a path to recover. + * In this case the that used for exclusion is the recovery path which is only known once + * the file has been loaded. + */ +bool WM_file_read(bContext *C, + const char *filepath, + const bool use_scripts_autoexec_check, + ReportList *reports); void WM_file_autosave_init(wmWindowManager *wm); -bool WM_file_recover_last_session(bContext *C, ReportList *reports); +bool WM_file_recover_last_session(bContext *C, + const bool use_scripts_autoexec_check, + ReportList *reports); void WM_file_tag_modified(); /** diff --git a/source/blender/windowmanager/intern/wm_files.cc b/source/blender/windowmanager/intern/wm_files.cc index e2ef05792ad..ac7c032a313 100644 --- a/source/blender/windowmanager/intern/wm_files.cc +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -1043,7 +1043,10 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) bf_reports->resynced_lib_overrides_libraries = nullptr; } -bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) +bool WM_file_read(bContext *C, + const char *filepath, + const bool use_scripts_autoexec_check, + ReportList *reports) { /* Assume automated tasks with background, don't write recent file list. */ const bool do_history_file_update = (G.background == false) && @@ -1110,6 +1113,14 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) G.f = (G.f & ~flags_keep) | (G_f_orig & flags_keep); } + /* Set by the `use_scripts` property on file load. + * If this was not set, then it should be calculated based on the file-path. + * Note that this uses `bmain->filepath` and not `filepath`, necessary when + * recovering the last session, where the file-path can be #BLENDER_QUIT_FILE. */ + if (use_scripts_autoexec_check) { + WM_file_autoexec_init(bmain->filepath); + } + WM_check(C); /* Opens window(s), checks keymaps. */ if (do_history_file_update) { @@ -2459,9 +2470,10 @@ void wm_open_init_load_ui(wmOperator *op, bool use_prefs) } } -void wm_open_init_use_scripts(wmOperator *op, bool use_prefs) +bool wm_open_init_use_scripts(wmOperator *op, bool use_prefs) { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts"); + bool use_scripts_autoexec_check = false; if (!RNA_property_is_set(op->ptr, prop)) { /* Use #G_FLAG_SCRIPT_AUTOEXEC rather than the userpref because this means if * the flag has been disabled from the command line, then opening @@ -2470,7 +2482,9 @@ void wm_open_init_use_scripts(wmOperator *op, bool use_prefs) ((G.f & G_FLAG_SCRIPT_AUTOEXEC) != 0); RNA_property_boolean_set(op->ptr, prop, value); + use_scripts_autoexec_check = true; } + return use_scripts_autoexec_check; } /** \} */ @@ -3065,18 +3079,16 @@ void WM_OT_read_factory_settings(wmOperatorType *ot) /** * Wrap #WM_file_read, shared by file reading operators. */ -static bool wm_file_read_opwrap(bContext *C, const char *filepath, ReportList *reports) +static bool wm_file_read_opwrap(bContext *C, + const char *filepath, + const bool use_scripts_autoexec_check, + ReportList *reports) { /* XXX: wm in context is not set correctly after #WM_file_read -> crash. */ /* Do it before for now, but is this correct with multiple windows? */ WM_event_add_notifier(C, NC_WINDOW, nullptr); - /* Set by the "use_scripts" property on file load. */ - if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) { - WM_file_autoexec_init(filepath); - } - - const bool success = WM_file_read(C, filepath, reports); + const bool success = WM_file_read(C, filepath, use_scripts_autoexec_check, reports); return success; } @@ -3179,7 +3191,8 @@ static wmOperatorStatus wm_open_mainfile__select_file_path_exec(bContext *C, wmO RNA_string_set(op->ptr, "filepath", blendfile_path); wm_open_init_load_ui(op, true); - wm_open_init_use_scripts(op, true); + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); + UNUSED_VARS(use_scripts_autoexec_check); /* The user can set this in the UI. */ op->customdata = nullptr; WM_event_add_fileselect(C, op); @@ -3200,11 +3213,11 @@ static wmOperatorStatus wm_open_mainfile__open(bContext *C, wmOperator *op) /* Re-use last loaded setting so we can reload a file without changing. */ wm_open_init_load_ui(op, false); - wm_open_init_use_scripts(op, false); + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, false); SET_FLAG_FROM_TEST(G.fileflags, !RNA_boolean_get(op->ptr, "load_ui"), G_FILE_NO_UI); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); - success = wm_file_read_opwrap(C, filepath, op->reports); + success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, op->reports); if (success) { if (G.fileflags & G_FILE_NO_UI) { @@ -3410,12 +3423,12 @@ static wmOperatorStatus wm_revert_mainfile_exec(bContext *C, wmOperator *op) bool success; char filepath[FILE_MAX]; - wm_open_init_use_scripts(op, false); + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, false); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); STRNCPY(filepath, BKE_main_blendfile_path(bmain)); - success = wm_file_read_opwrap(C, filepath, op->reports); + success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, op->reports); if (success) { return OPERATOR_FINISHED; @@ -3448,21 +3461,24 @@ void WM_OT_revert_mainfile(wmOperatorType *ot) /** \name Recover Last Session Operator * \{ */ -bool WM_file_recover_last_session(bContext *C, ReportList *reports) +bool WM_file_recover_last_session(bContext *C, + const bool use_scripts_autoexec_check, + ReportList *reports) { char filepath[FILE_MAX]; BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE); G.fileflags |= G_FILE_RECOVER_READ; - const bool success = wm_file_read_opwrap(C, filepath, reports); + const bool success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, reports); G.fileflags &= ~G_FILE_RECOVER_READ; return success; } -static wmOperatorStatus wm_recover_last_session_exec(bContext *C, wmOperator *op) +static wmOperatorStatus wm_recover_last_session_impl(bContext *C, + wmOperator *op, + const bool use_scripts_autoexec_check) { - wm_open_init_use_scripts(op, true); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); - if (WM_file_recover_last_session(C, op->reports)) { + if (WM_file_recover_last_session(C, use_scripts_autoexec_check, op->reports)) { if (!G.background) { wmOperatorType *ot = op->type; PointerRNA *props_ptr = MEM_new(__func__); @@ -3475,6 +3491,12 @@ static wmOperatorStatus wm_recover_last_session_exec(bContext *C, wmOperator *op return OPERATOR_CANCELLED; } +static wmOperatorStatus wm_recover_last_session_exec(bContext *C, wmOperator *op) +{ + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); + return wm_recover_last_session_impl(C, op, use_scripts_autoexec_check); +} + static void wm_recover_last_session_after_dialog_callback(bContext *C, void *user_data) { WM_operator_name_call_with_properties( @@ -3487,14 +3509,14 @@ static wmOperatorStatus wm_recover_last_session_invoke(bContext *C, { /* Keep the current setting instead of using the preferences since a file selector * doesn't give us the option to change the setting. */ - wm_open_init_use_scripts(op, false); + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, false); if (wm_operator_close_file_dialog_if_needed( C, op, wm_recover_last_session_after_dialog_callback)) { return OPERATOR_INTERFACE; } - return wm_recover_last_session_exec(C, op); + return wm_recover_last_session_impl(C, op, use_scripts_autoexec_check); } void WM_OT_recover_last_session(wmOperatorType *ot) @@ -3523,12 +3545,12 @@ static wmOperatorStatus wm_recover_auto_save_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", filepath); BLI_path_canonicalize_native(filepath, sizeof(filepath)); - wm_open_init_use_scripts(op, true); + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); G.fileflags |= G_FILE_RECOVER_READ; - success = wm_file_read_opwrap(C, filepath, op->reports); + success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, op->reports); G.fileflags &= ~G_FILE_RECOVER_READ; @@ -3553,7 +3575,8 @@ static wmOperatorStatus wm_recover_auto_save_invoke(bContext *C, wm_autosave_location(filepath); RNA_string_set(op->ptr, "filepath", filepath); - wm_open_init_use_scripts(op, true); + const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); + UNUSED_VARS(use_scripts_autoexec_check); /* The user can set this in the UI. */ WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/windowmanager/wm.hh b/source/blender/windowmanager/wm.hh index d6d71fb0966..4db8925d996 100644 --- a/source/blender/windowmanager/wm.hh +++ b/source/blender/windowmanager/wm.hh @@ -8,6 +8,8 @@ #pragma once +#include "BLI_compiler_attrs.h" + struct wmOperator; struct wmTimer; struct wmWindow; @@ -119,4 +121,7 @@ void wm_stereo3d_set_cancel(bContext *C, wmOperator *op); * Initialize operator properties. */ void wm_open_init_load_ui(wmOperator *op, bool use_prefs); -void wm_open_init_use_scripts(wmOperator *op, bool use_prefs); +/** + * Return true if the script auto-execution should be cleared based on #WM_file_autoexec_init. + */ +bool wm_open_init_use_scripts(wmOperator *op, bool use_prefs) ATTR_WARN_UNUSED_RESULT; diff --git a/source/creator/creator_args.cc b/source/creator/creator_args.cc index a7e5f0e7702..42d472a9235 100644 --- a/source/creator/creator_args.cc +++ b/source/creator/creator_args.cc @@ -2535,8 +2535,11 @@ static bool handle_load_file(bContext *C, const char *filepath_arg, const bool l /* Load the file. */ ReportList reports; BKE_reports_init(&reports, RPT_PRINT); - WM_file_autoexec_init(filepath); - const bool success = WM_file_read(C, filepath, &reports); + /* When activating from the command line there isn't an exact equivalent to operator properties. + * Instead, enabling auto-execution via `--enable-autoexec` causes the auto-execution + * check to be skipped (if it's set), so it's fine to always enable the check here. */ + const bool use_scripts_autoexec_check = true; + const bool success = WM_file_read(C, filepath, use_scripts_autoexec_check, &reports); BKE_reports_free(&reports); if (success) {