diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_keymap.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 152 |
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); } |