PyAPI: postpone loading add-ons until after key-maps have been defined
Loading add-ons after key-maps resolves a problem where add-ons would setup shortcuts before Blender had created the key-maps. Making add-ons have to declare the key-maps using region & window types matching Blender's internal values. This PR a pitfall pointed out in #110030. Ref !110092
This commit is contained in:
parent
bedfc68e3f
commit
6de294a191
@ -57,7 +57,9 @@ def main():
|
||||
|
||||
# Initializes Python classes.
|
||||
# (good place to run a profiler or trace).
|
||||
utils.load_scripts()
|
||||
# Postpone loading `extensions` scripts (add-ons & app-templates),
|
||||
# until after the key-maps have been initialized.
|
||||
utils.load_scripts(extensions=False)
|
||||
|
||||
|
||||
main()
|
||||
|
@ -189,7 +189,7 @@ _global_loaded_modules = [] # store loaded module names for reloading.
|
||||
import bpy_types as _bpy_types # keep for comparisons, never ever reload this.
|
||||
|
||||
|
||||
def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
||||
def load_scripts(*, reload_scripts=False, refresh_scripts=False, extensions=True):
|
||||
"""
|
||||
Load scripts and run each modules register function.
|
||||
|
||||
@ -199,6 +199,8 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
||||
:arg refresh_scripts: only load scripts which are not already loaded
|
||||
as modules.
|
||||
:type refresh_scripts: bool
|
||||
:arg: extensions: Loads additional scripts (add-ons & app-templates).
|
||||
:type: extensions: bool
|
||||
"""
|
||||
use_time = use_class_register_check = _bpy.app.debug_python
|
||||
use_user = not _is_factory_startup
|
||||
@ -306,21 +308,8 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
||||
for mod in modules_from_path(path, loaded_modules):
|
||||
test_register(mod)
|
||||
|
||||
# load template (if set)
|
||||
if any(_bpy.utils.app_template_paths()):
|
||||
import bl_app_template_utils
|
||||
bl_app_template_utils.reset(reload_scripts=reload_scripts)
|
||||
del bl_app_template_utils
|
||||
|
||||
# Deal with add-ons separately.
|
||||
_initialize_once = getattr(_addon_utils, "_initialize_once", None)
|
||||
if _initialize_once is not None:
|
||||
# First time, use fast-path.
|
||||
_initialize_once()
|
||||
del _addon_utils._initialize_once
|
||||
else:
|
||||
_addon_utils.reset_all(reload_scripts=reload_scripts)
|
||||
del _initialize_once
|
||||
if extensions:
|
||||
load_scripts_extensions(reload_scripts=reload_scripts)
|
||||
|
||||
if reload_scripts:
|
||||
_bpy.context.window_manager.tag_script_reload()
|
||||
@ -342,6 +331,31 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
||||
)
|
||||
|
||||
|
||||
def load_scripts_extensions(*, reload_scripts=False):
|
||||
"""
|
||||
Load extensions scripts (add-ons and app-templates)
|
||||
|
||||
:arg reload_scripts: Causes all scripts to have their unregister method
|
||||
called before loading.
|
||||
:type reload_scripts: bool
|
||||
"""
|
||||
# load template (if set)
|
||||
if any(_bpy.utils.app_template_paths()):
|
||||
import bl_app_template_utils
|
||||
bl_app_template_utils.reset(reload_scripts=reload_scripts)
|
||||
del bl_app_template_utils
|
||||
|
||||
# deal with addons separately
|
||||
_initialize = getattr(_addon_utils, "_initialize", None)
|
||||
if _initialize is not None:
|
||||
# first time, use fast-path
|
||||
_initialize()
|
||||
del _addon_utils._initialize
|
||||
else:
|
||||
_addon_utils.reset_all(reload_scripts=reload_scripts)
|
||||
del _initialize
|
||||
|
||||
|
||||
def script_path_user():
|
||||
"""returns the env var and falls back to home dir or None"""
|
||||
path = _user_resource('SCRIPTS')
|
||||
|
@ -133,6 +133,8 @@ CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_TOOLS, "wm.tool");
|
||||
CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_MSGBUS_PUB, "wm.msgbus.pub");
|
||||
CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_MSGBUS_SUB, "wm.msgbus.sub");
|
||||
|
||||
static void wm_init_scripts_extensions_once(bContext *C);
|
||||
|
||||
static void wm_init_reports(bContext *C)
|
||||
{
|
||||
ReportList *reports = CTX_wm_reports(C);
|
||||
@ -358,6 +360,13 @@ void WM_init(bContext *C, int argc, const char **argv)
|
||||
|
||||
STRNCPY(G.lib, BKE_main_blendfile_path_from_global());
|
||||
|
||||
CTX_py_init_set(C, true);
|
||||
WM_keyconfig_init(C);
|
||||
|
||||
/* Load add-ons after key-maps have been initialized (but before the blend file has been read),
|
||||
* important to guarantee default key-maps have been declared & before post-read handlers run. */
|
||||
wm_init_scripts_extensions_once(C);
|
||||
|
||||
wm_homefile_read_post(C, params_file_read_post);
|
||||
}
|
||||
|
||||
@ -416,6 +425,13 @@ void WM_init_splash(bContext *C)
|
||||
CTX_wm_window_set(C, prevwin);
|
||||
}
|
||||
|
||||
/** Load add-ons & app-templates once on startup. */
|
||||
static void wm_init_scripts_extensions_once(bContext *C)
|
||||
{
|
||||
const char *imports[] = {"bpy", nullptr};
|
||||
BPY_run_string_eval(C, imports, "bpy.utils.load_scripts_extensions()");
|
||||
}
|
||||
|
||||
/* free strings of open recent files */
|
||||
static void free_openrecent()
|
||||
{
|
||||
|
@ -545,9 +545,6 @@ int main(int argc,
|
||||
"this is not intended for typical usage\n\n");
|
||||
#endif
|
||||
|
||||
CTX_py_init_set(C, true);
|
||||
WM_keyconfig_init(C);
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
/* Initialize Freestyle. */
|
||||
FRS_init();
|
||||
|
Loading…
x
Reference in New Issue
Block a user