Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_keymap.c')
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c152
1 files changed, 114 insertions, 38 deletions
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index b52f3819d3f..82e46c1b333 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -145,21 +145,15 @@ static void wm_keyconfig_properties_update_ot(ListBase *km_lb)
}
}
-static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
+static bool wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
{
- if (strcmp(a->idname, b->idname) != 0)
- return 0;
-
- if (!RNA_struct_equals(a->ptr, b->ptr, RNA_EQ_UNSET_MATCH_NONE))
- return 0;
-
- if ((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE))
- return 0;
-
- return (a->propvalue == b->propvalue);
+ return (STREQ(a->idname, b->idname) &&
+ RNA_struct_equals(a->ptr, b->ptr, RNA_EQ_UNSET_MATCH_NONE) &&
+ (a->flag & KMI_INACTIVE) == (b->flag & KMI_INACTIVE) &&
+ a->propvalue == b->propvalue);
}
-static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
+static bool wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
{
return (wm_keymap_item_equals_result(a, b) &&
a->type == b->type &&
@@ -266,7 +260,7 @@ wmKeyConfig *WM_keyconfig_new_user(wmWindowManager *wm, const char *idname)
bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
{
if (BLI_findindex(&wm->keyconfigs, keyconf) != -1) {
- if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) {
+ if (STREQLEN(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr))) {
BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
WM_keyconfig_update_tag(NULL, NULL);
}
@@ -421,7 +415,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty
wmKeyMapItem *kmi;
for (kmi = keymap->items.first; kmi; kmi = kmi->next)
- if (strncmp(kmi->idname, idname, OP_MAX_TYPENAME) == 0)
+ if (STREQLEN(kmi->idname, idname, OP_MAX_TYPENAME))
break;
if (kmi == NULL) {
kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
@@ -728,7 +722,7 @@ wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int
for (km = lb->first; km; km = km->next)
if (km->spaceid == spaceid && km->regionid == regionid)
- if (0 == strncmp(idname, km->idname, KMAP_MAX_NAME))
+ if (STREQLEN(idname, km->idname, KMAP_MAX_NAME))
return km;
return NULL;
@@ -787,7 +781,7 @@ wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, const char *idname)
for (km = keyconf->keymaps.first; km; km = km->next)
if (km->flag & KEYMAP_MODAL)
- if (0 == strncmp(idname, km->idname, KMAP_MAX_NAME))
+ if (STREQLEN(idname, km->idname, KMAP_MAX_NAME))
break;
return km;
@@ -952,18 +946,17 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(
if (kmi->flag & KMI_INACTIVE)
continue;
- if (strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) {
+ if (STREQ(kmi->idname, opname) && WM_key_event_string(kmi->type)[0]) {
if (is_hotkey) {
if (!ISHOTKEY(kmi->type))
continue;
}
if (properties) {
-
/* example of debugging keymaps */
#if 0
if (kmi->ptr) {
- if (strcmp("MESH_OT_rip_move", opname) == 0) {
+ if (STREQ("MESH_OT_rip_move", opname)) {
printf("OPERATOR\n");
IDP_spit(properties);
printf("KEYMAP\n");
@@ -976,6 +969,39 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(
if (keymap_r) *keymap_r = keymap;
return kmi;
}
+ /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
+ else if (G.debug & G_DEBUG_WM) {
+ if (is_strict && kmi->ptr) {
+ wmOperatorType *ot = WM_operatortype_find(opname, true);
+ if (ot) {
+ /* make a copy of the properties and set unset ones to their default values. */
+ PointerRNA opptr;
+ IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data);
+
+ RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+ WM_operator_properties_default(&opptr, true);
+
+ if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) {
+ char kmi_str[128];
+ WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str));
+ /* Note gievn properties could come from other things than menu entry... */
+ printf("%s: Some set values in menu entry match default op values, "
+ "this might not be desired!\n", opname);
+ printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str);
+#ifndef NDEBUG
+ printf("OPERATOR\n");
+ IDP_spit(properties);
+ printf("KEYMAP\n");
+ IDP_spit(kmi->ptr->data);
+#endif
+ printf("\n");
+ }
+
+ IDP_FreeProperty(properties_default);
+ MEM_freeN(properties_default);
+ }
+ }
+ }
}
else {
if (keymap_r) *keymap_r = keymap;
@@ -1042,33 +1068,83 @@ static wmKeyMapItem *wm_keymap_item_find_props(
static wmKeyMapItem *wm_keymap_item_find(
const bContext *C, const char *opname, int opcontext,
- IDProperty *properties, const bool is_hotkey, const bool is_strict, wmKeyMap **keymap_r)
+ IDProperty *properties, const bool is_hotkey, bool is_strict, wmKeyMap **keymap_r)
{
- wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, is_strict, is_hotkey, keymap_r);
+ wmKeyMapItem *found;
+ /* XXX Hack! Macro operators in menu entry have their whole props defined, which is not the case for
+ * relevant keymap entries. Could be good to check and harmonize this, but for now always
+ * compare non-strict in this case.
+ */
+ wmOperatorType *ot = WM_operatortype_find(opname, true);
+ if (ot) {
+ is_strict = is_strict && ((ot->flag & OPTYPE_MACRO) == 0);
+ }
+
+ found = wm_keymap_item_find_props(C, opname, opcontext, properties, is_strict, is_hotkey, keymap_r);
+
+ /* This block is *only* useful in one case: when op uses an enum menu in its prop member
+ * (then, we want to rerun a comparison with that 'prop' unset). Note this remains brittle,
+ * since now any enum prop may be used in UI (specified by name), ot->prop is not so much used...
+ * Otherwise:
+ * * If non-strict, unset properties always match set ones in IDP_EqualsProperties_ex.
+ * * If strict, unset properties never match set ones in IDP_EqualsProperties_ex,
+ * and we do not want that to change (else we get things like T41757)!
+ * ...so in either case, re-running a comparison with unset props set to default is useless.
+ */
if (!found && properties) {
- wmOperatorType *ot = WM_operatortype_find(opname, true);
- if (ot) {
- /* make a copy of the properties and set any unset props
- * to their default values, so the ID property compare function succeeds */
+ if (ot && ot->prop) { /* XXX Shall we also check ot->prop is actually an enum? */
+ /* make a copy of the properties and unset the 'ot->prop' one if set. */
PointerRNA opptr;
- IDProperty *properties_default = IDP_CopyProperty(properties);
+ IDProperty *properties_temp = IDP_CopyProperty(properties);
- RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+ RNA_pointer_create(NULL, ot->srna, properties_temp, &opptr);
- if (WM_operator_properties_default(&opptr, true) ||
- (!is_strict && ot->prop && RNA_property_is_set(&opptr, ot->prop)))
- {
- /* for operator that has enum menu, unset it so it always matches */
- if (!is_strict && ot->prop) {
- RNA_property_unset(&opptr, ot->prop);
- }
+ if (RNA_property_is_set(&opptr, ot->prop)) {
+ /* for operator that has enum menu, unset it so its value does not affect comparison result */
+ RNA_property_unset(&opptr, ot->prop);
- found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, false, is_hotkey, keymap_r);
+ found = wm_keymap_item_find_props(C, opname, opcontext, properties_temp,
+ is_strict, is_hotkey, keymap_r);
}
- IDP_FreeProperty(properties_default);
- MEM_freeN(properties_default);
+ IDP_FreeProperty(properties_temp);
+ MEM_freeN(properties_temp);
+ }
+ }
+
+ /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
+ if (G.debug & G_DEBUG_WM) {
+ if (!found && is_strict && properties) {
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ if (ot) {
+ /* make a copy of the properties and set unset ones to their default values. */
+ PointerRNA opptr;
+ IDProperty *properties_default = IDP_CopyProperty(properties);
+
+ RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+ WM_operator_properties_default(&opptr, true);
+
+ kmi = wm_keymap_item_find_props(C, opname, opcontext, properties_default, is_strict, is_hotkey, &km);
+ if (kmi) {
+ char kmi_str[128];
+ WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str));
+ printf("%s: Some set values in keymap entry match default op values, "
+ "this might not be desired!\n", opname);
+ printf("\tkm: '%s', kmi: '%s'\n", km->idname, kmi_str);
+#ifndef NDEBUG
+ printf("OPERATOR\n");
+ IDP_spit(properties);
+ printf("KEYMAP\n");
+ IDP_spit(kmi->ptr->data);
+#endif
+ printf("\n");
+ }
+
+ IDP_FreeProperty(properties_default);
+ MEM_freeN(properties_default);
+ }
}
}
@@ -1353,7 +1429,7 @@ void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapIt
if (orig) {
/* restore to original */
- if (strcmp(orig->idname, kmi->idname) != 0) {
+ if (!STREQ(orig->idname, kmi->idname)) {
BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
WM_keymap_properties_reset(kmi, NULL);
}