WM: resolve transform triggering key-maps to be rebuilt

Since [0] modal transform in the 3D viewport caused key-maps to be
rebuilt by the event system. Creating a temporary copy for
ViewOpsData_Utility flagged the key-map as outdated.

This could crash (resolved by [1] - for the most-part), but would still
rebuild the whole key-map, adding unnecessary overhead.

This would also reset the KMI_EXPANDED flag, causing transform
to hide key-map items when using Blender with the key-map editor open.

Add a function to temporarily suppress key-map updates.
While not ideal, full support for temporary key-maps that behave
differently to user key-maps is a bigger project for something
that's only needed in one place.

[0]: 017d4912b2
[1]: 9a0eaa2062
This commit is contained in:
Campbell Barton
2023-09-17 13:23:24 +10:00
parent edc47d3d5a
commit 1cda66b911
3 changed files with 44 additions and 0 deletions

View File

@@ -412,6 +412,9 @@ struct ViewOpsData_Utility : ViewOpsData {
wmKeyMap *keymap = WM_keymap_find_all(
CTX_wm_manager(C), "3D View", SPACE_VIEW3D, RGN_TYPE_WINDOW);
WM_keyconfig_update_suppress_begin();
wmKeyMap keymap_tmp = {};
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
@@ -433,14 +436,20 @@ struct ViewOpsData_Utility : ViewOpsData {
/* Weak, but only the keymap items from the #wmKeyMap struct are needed here. */
this->keymap_items = keymap_tmp.items;
WM_keyconfig_update_suppress_end();
}
~ViewOpsData_Utility()
{
/* Weak, but rebuild the struct #wmKeyMap to clear the keymap items. */
WM_keyconfig_update_suppress_begin();
wmKeyMap keymap_tmp = {};
keymap_tmp.items = this->keymap_items;
WM_keymap_clear(&keymap_tmp);
WM_keyconfig_update_suppress_end();
}
#ifdef WITH_CXX_GUARDEDALLOC

View File

@@ -31,6 +31,9 @@ void WM_keyconfig_update(wmWindowManager *wm);
void WM_keyconfig_update_tag(wmKeyMap *keymap, wmKeyMapItem *kmi);
void WM_keyconfig_update_operatortype();
void WM_keyconfig_update_suppress_begin();
void WM_keyconfig_update_suppress_end();
/* Keymap */
/** Parameters for matching events, passed into functions that create key-map items. */

View File

@@ -1795,6 +1795,11 @@ enum {
static char wm_keymap_update_flag = 0;
static char wm_keymap_update_suppress_flag = 0;
#ifndef NDEBUG
static int8_t wm_keymap_update_suppress_count = 0;
#endif
void WM_keyconfig_update_tag(wmKeyMap *keymap, wmKeyMapItem *kmi)
{
/* quick tag to do delayed keymap updates */
@@ -1813,6 +1818,33 @@ void WM_keyconfig_update_operatortype()
wm_keymap_update_flag |= WM_KEYMAP_UPDATE_OPERATORTYPE;
}
/* NOTE(@ideasman42): regarding suppressing updates.
* If this becomes a common operation it would be better use something more general,
* a key-map flag for e.g. to signify that the key-map is stored outside of a #wmKeyConfig
* and should not receive updates on modification. At the moment this has the down-side of
* needing to be supported in quite a few places for something which isn't used much.
* Since the use case for this is limited, add functions to begin/end suppression.
* If these end up being used a lot we can consider alternatives. */
void WM_keyconfig_update_suppress_begin()
{
#ifndef NDEBUG
BLI_assert(wm_keymap_update_suppress_count == 0);
wm_keymap_update_suppress_count += 1;
#endif
wm_keymap_update_suppress_flag = wm_keymap_update_flag;
}
void WM_keyconfig_update_suppress_end()
{
#ifndef NDEBUG
BLI_assert(wm_keymap_update_suppress_count == 1);
wm_keymap_update_suppress_count -= 1;
#endif
wm_keymap_update_flag = wm_keymap_update_suppress_flag;
wm_keymap_update_suppress_flag = 0;
}
static bool wm_keymap_test_and_clear_update(wmKeyMap *km)
{
int update = (km->flag & KEYMAP_UPDATE);