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.
|
# Initializes Python classes.
|
||||||
# (good place to run a profiler or trace).
|
# (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()
|
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.
|
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.
|
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
|
:arg refresh_scripts: only load scripts which are not already loaded
|
||||||
as modules.
|
as modules.
|
||||||
:type refresh_scripts: bool
|
: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_time = use_class_register_check = _bpy.app.debug_python
|
||||||
use_user = not _is_factory_startup
|
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):
|
for mod in modules_from_path(path, loaded_modules):
|
||||||
test_register(mod)
|
test_register(mod)
|
||||||
|
|
||||||
# load template (if set)
|
if extensions:
|
||||||
if any(_bpy.utils.app_template_paths()):
|
load_scripts_extensions(reload_scripts=reload_scripts)
|
||||||
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 reload_scripts:
|
if reload_scripts:
|
||||||
_bpy.context.window_manager.tag_script_reload()
|
_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():
|
def script_path_user():
|
||||||
"""returns the env var and falls back to home dir or None"""
|
"""returns the env var and falls back to home dir or None"""
|
||||||
path = _user_resource('SCRIPTS')
|
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_PUB, "wm.msgbus.pub");
|
||||||
CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_MSGBUS_SUB, "wm.msgbus.sub");
|
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)
|
static void wm_init_reports(bContext *C)
|
||||||
{
|
{
|
||||||
ReportList *reports = CTX_wm_reports(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());
|
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);
|
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);
|
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 */
|
/* free strings of open recent files */
|
||||||
static void free_openrecent()
|
static void free_openrecent()
|
||||||
{
|
{
|
||||||
|
@ -545,9 +545,6 @@ int main(int argc,
|
|||||||
"this is not intended for typical usage\n\n");
|
"this is not intended for typical usage\n\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CTX_py_init_set(C, true);
|
|
||||||
WM_keyconfig_init(C);
|
|
||||||
|
|
||||||
#ifdef WITH_FREESTYLE
|
#ifdef WITH_FREESTYLE
|
||||||
/* Initialize Freestyle. */
|
/* Initialize Freestyle. */
|
||||||
FRS_init();
|
FRS_init();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user