Blender  V2.93
wm_keymap.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include <string.h>
27 
28 #include "DNA_object_types.h"
29 #include "DNA_screen_types.h"
30 #include "DNA_space_types.h"
31 #include "DNA_userdef_types.h"
33 #include "DNA_workspace_types.h"
34 
35 #include "CLG_log.h"
36 #include "MEM_guardedalloc.h"
37 
38 #include "BLI_blenlib.h"
39 #include "BLI_math.h"
40 #include "BLI_utildefines.h"
41 
42 #include "BLF_api.h"
43 
44 #include "BKE_context.h"
45 #include "BKE_global.h"
46 #include "BKE_idprop.h"
47 #include "BKE_main.h"
48 #include "BKE_screen.h"
49 #include "BKE_workspace.h"
50 
51 #include "BLT_translation.h"
52 
53 #include "RNA_access.h"
54 #include "RNA_enum_types.h"
55 
56 #include "WM_api.h"
57 #include "WM_types.h"
58 #include "wm_event_system.h"
59 #include "wm_event_types.h"
60 
62  bool (*filter_fn)(const wmKeyMap *km, const wmKeyMapItem *kmi, void *user_data);
63  void *user_data;
64 };
65 
66 /* -------------------------------------------------------------------- */
73 {
74  wmKeyMapItem *kmin = MEM_dupallocN(kmi);
75 
76  kmin->prev = kmin->next = NULL;
77  kmin->flag &= ~KMI_UPDATE;
78 
79  if (kmin->properties) {
80  kmin->ptr = MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
82 
83  /* Signal for no context, see #STRUCT_NO_CONTEXT_WITHOUT_OWNER_ID. */
84  kmin->ptr->owner_id = NULL;
85 
86  kmin->properties = IDP_CopyProperty(kmin->properties);
87  kmin->ptr->data = kmin->properties;
88  }
89  else {
90  kmin->properties = NULL;
91  kmin->ptr = NULL;
92  }
93 
94  return kmin;
95 }
96 
98 {
99  /* not kmi itself */
100  if (kmi->ptr) {
102  MEM_freeN(kmi->ptr);
103  kmi->ptr = NULL;
104  kmi->properties = NULL;
105  }
106 }
107 
109 {
110  WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname);
112 
113  /* Signal for no context, see #STRUCT_NO_CONTEXT_WITHOUT_OWNER_ID. */
114  kmi->ptr->owner_id = NULL;
115 }
116 
122 {
123  if (kmi->idname[0] == 0) {
124  BLI_assert(kmi->ptr == NULL);
125  return;
126  }
127 
128  if (kmi->ptr == NULL) {
130  }
131  else {
133  if (ot) {
134  if (ot->srna != kmi->ptr->type) {
135  /* matches wm_keymap_item_properties_set but doesn't alloc new ptr */
137  /* 'kmi->ptr->data' NULL'd above, keep using existing properties.
138  * Note: the operators property types may have changed,
139  * we will need a more comprehensive sanitize function to support this properly.
140  */
141  if (kmi->properties) {
142  kmi->ptr->data = kmi->properties;
143  }
145 
146  /* Signal for no context, see #STRUCT_NO_CONTEXT_WITHOUT_OWNER_ID. */
147  kmi->ptr->owner_id = NULL;
148  }
149  }
150  else {
151  /* zombie keymap item */
152  wm_keymap_item_free(kmi);
153  }
154  }
155 }
156 
158 {
159  LISTBASE_FOREACH (wmKeyMap *, km, km_lb) {
160  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
162  }
163 
164  LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
165  if (kmdi->add_item) {
166  wm_keymap_item_properties_update_ot(kmdi->add_item);
167  }
168  if (kmdi->remove_item) {
169  wm_keymap_item_properties_update_ot(kmdi->remove_item);
170  }
171  }
172  }
173 }
174 
176 {
177  return (STREQ(a->idname, b->idname) &&
178  /* We do not really care about which Main we pass here, tbh. */
180  (a->flag & KMI_INACTIVE) == (b->flag & KMI_INACTIVE) && a->propvalue == b->propvalue);
181 }
182 
184 {
185  return (wm_keymap_item_equals_result(a, b) && a->type == b->type && a->val == b->val &&
186  a->shift == b->shift && a->ctrl == b->ctrl && a->alt == b->alt && a->oskey == b->oskey &&
187  a->keymodifier == b->keymodifier && a->maptype == b->maptype &&
188  ((ISKEYBOARD(a->type) == 0) ||
189  (a->flag & KMI_REPEAT_IGNORE) == (b->flag & KMI_REPEAT_IGNORE)));
190 }
191 
192 /* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */
194 {
195  if (LIKELY(kmi->ptr)) {
197  MEM_freeN(kmi->ptr);
198 
199  kmi->ptr = NULL;
200  }
201 
202  kmi->properties = properties;
203 
205 }
206 
208 {
209  if (ISTIMER(kmi->type)) {
210  return KMI_TYPE_TIMER;
211  }
212  if (ISKEYBOARD(kmi->type)) {
213  return KMI_TYPE_KEYBOARD;
214  }
215  if (ISTWEAK(kmi->type)) {
216  return KMI_TYPE_TWEAK;
217  }
218  if (ISMOUSE(kmi->type)) {
219  return KMI_TYPE_MOUSE;
220  }
221  if (ISNDOF(kmi->type)) {
222  return KMI_TYPE_NDOF;
223  }
224  if (kmi->type == KM_TEXTINPUT) {
225  return KMI_TYPE_TEXTINPUT;
226  }
227  if (ELEM(kmi->type, TABLET_STYLUS, TABLET_ERASER)) {
228  return KMI_TYPE_MOUSE;
229  }
230  return KMI_TYPE_KEYBOARD;
231 }
232 
235 /* -------------------------------------------------------------------- */
242 {
243  wmKeyMapDiffItem *kmdin = MEM_dupallocN(kmdi);
244 
245  kmdin->next = kmdin->prev = NULL;
246  if (kmdi->add_item) {
247  kmdin->add_item = wm_keymap_item_copy(kmdi->add_item);
248  }
249  if (kmdi->remove_item) {
251  }
252 
253  return kmdin;
254 }
255 
257 {
258  if (kmdi->remove_item) {
260  MEM_freeN(kmdi->remove_item);
261  }
262  if (kmdi->add_item) {
264  MEM_freeN(kmdi->add_item);
265  }
266 }
267 
270 /* -------------------------------------------------------------------- */
278 wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname, bool user_defined)
279 {
280  wmKeyConfig *keyconf = BLI_findstring(&wm->keyconfigs, idname, offsetof(wmKeyConfig, idname));
281  if (keyconf) {
282  if (keyconf == wm->defaultconf) {
283  /* For default configuration, we need to keep keymap
284  * modal items and poll functions intact. */
285  LISTBASE_FOREACH (wmKeyMap *, km, &keyconf->keymaps) {
286  WM_keymap_clear(km);
287  }
288  }
289  else {
290  /* For user defined key configuration, clear all keymaps. */
291  WM_keyconfig_clear(keyconf);
292  }
293 
294  return keyconf;
295  }
296 
297  /* Create new configuration. */
298  keyconf = MEM_callocN(sizeof(wmKeyConfig), "wmKeyConfig");
299  BLI_strncpy(keyconf->idname, idname, sizeof(keyconf->idname));
300  BLI_addtail(&wm->keyconfigs, keyconf);
301 
302  if (user_defined) {
303  keyconf->flag |= KEYCONF_USER;
304  }
305 
306  return keyconf;
307 }
308 
310 {
311  return WM_keyconfig_new(wm, idname, true);
312 }
313 
315 {
316  if (BLI_findindex(&wm->keyconfigs, keyconf) != -1) {
317  if (STREQLEN(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr))) {
318  BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
319  U.runtime.is_dirty = true;
321  }
322 
323  BLI_remlink(&wm->keyconfigs, keyconf);
324  WM_keyconfig_free(keyconf);
325 
326  return true;
327  }
328  return false;
329 }
330 
332 {
333  LISTBASE_FOREACH (wmKeyMap *, km, &keyconf->keymaps) {
334  WM_keymap_clear(km);
335  }
336 
337  BLI_freelistN(&keyconf->keymaps);
338 }
339 
341 {
342  WM_keyconfig_clear(keyconf);
343  MEM_freeN(keyconf);
344 }
345 
347 {
348  wmKeyConfig *keyconf;
349 
350  /* first try from preset */
351  keyconf = BLI_findstring(&wm->keyconfigs, U.keyconfigstr, offsetof(wmKeyConfig, idname));
352  if (keyconf) {
353  return keyconf;
354  }
355 
356  /* otherwise use default */
357  return wm->defaultconf;
358 }
359 
360 void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
361 {
362  /* setting a different key configuration as active: we ensure all is
363  * updated properly before and after making the change */
364 
366 
367  BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr));
368  if (wm->initialized & WM_KEYCONFIG_IS_INIT) {
369  U.runtime.is_dirty = true;
370  }
371 
374 }
375 
378 /* -------------------------------------------------------------------- */
384 static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid)
385 {
386  wmKeyMap *km = MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
387 
388  BLI_strncpy(km->idname, idname, KMAP_MAX_NAME);
389  km->spaceid = spaceid;
390  km->regionid = regionid;
391 
392  {
393  const char *owner_id = RNA_struct_state_owner_get();
394  if (owner_id) {
395  BLI_strncpy(km->owner_id, owner_id, sizeof(km->owner_id));
396  }
397  }
398  return km;
399 }
400 
402 {
403  wmKeyMap *keymapn = MEM_dupallocN(keymap);
404 
405  keymapn->modal_items = keymap->modal_items;
406  keymapn->poll = keymap->poll;
407  keymapn->poll_modal_item = keymap->poll_modal_item;
408  BLI_listbase_clear(&keymapn->items);
409  keymapn->flag &= ~(KEYMAP_UPDATE | KEYMAP_EXPANDED);
410 
411  LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) {
412  wmKeyMapDiffItem *kmdi_new = wm_keymap_diff_item_copy(kmdi);
413  BLI_addtail(&keymapn->items, kmdi_new);
414  }
415 
416  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
417  wmKeyMapItem *kmi_new = wm_keymap_item_copy(kmi);
418  BLI_addtail(&keymapn->items, kmi_new);
419  }
420 
421  return keymapn;
422 }
423 
425 {
426  LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) {
428  }
429 
430  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
431  wm_keymap_item_free(kmi);
432  }
433 
434  BLI_freelistN(&keymap->diff_items);
435  BLI_freelistN(&keymap->items);
436 }
437 
438 bool WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
439 {
440  if (BLI_findindex(&keyconf->keymaps, keymap) != -1) {
441 
442  WM_keymap_clear(keymap);
443  BLI_remlink(&keyconf->keymaps, keymap);
444  MEM_freeN(keymap);
445 
446  return true;
447  }
448  return false;
449 }
450 
452 {
453  /* If we're tagged, only use compatible. */
454  if (keymap->owner_id[0] != '\0') {
455  const WorkSpace *workspace = CTX_wm_workspace(C);
456  if (BKE_workspace_owner_id_check(workspace, keymap->owner_id) == false) {
457  return false;
458  }
459  }
460 
461  if (UNLIKELY(BLI_listbase_is_empty(&keymap->items))) {
462  /* Empty key-maps may be missing more there may be a typo in the name.
463  * Warn early to avoid losing time investigating each case. */
464  CLOG_WARN(WM_LOG_KEYMAPS, "empty keymap '%s'", keymap->idname);
465  }
466 
467  if (keymap->poll != NULL) {
468  return keymap->poll(C);
469  }
470  return true;
471 }
472 
473 static void keymap_event_set(
474  wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier)
475 {
476  kmi->type = type;
477  kmi->val = val;
478  kmi->keymodifier = keymodifier;
479 
480  if (modifier == KM_ANY) {
481  kmi->shift = kmi->ctrl = kmi->alt = kmi->oskey = KM_ANY;
482  }
483  else {
484  kmi->shift = (modifier & KM_SHIFT) ? KM_MOD_FIRST :
485  ((modifier & KM_SHIFT2) ? KM_MOD_SECOND : false);
486  kmi->ctrl = (modifier & KM_CTRL) ? KM_MOD_FIRST :
487  ((modifier & KM_CTRL2) ? KM_MOD_SECOND : false);
488  kmi->alt = (modifier & KM_ALT) ? KM_MOD_FIRST : ((modifier & KM_ALT2) ? KM_MOD_SECOND : false);
489  kmi->oskey = (modifier & KM_OSKEY) ? KM_MOD_FIRST :
490  ((modifier & KM_OSKEY2) ? KM_MOD_SECOND : false);
491  }
492 }
493 
494 static void keymap_item_set_id(wmKeyMap *keymap, wmKeyMapItem *kmi)
495 {
496  keymap->kmi_id++;
497  if ((keymap->flag & KEYMAP_USER) == 0) {
498  kmi->id = keymap->kmi_id;
499  }
500  else {
501  kmi->id = -keymap->kmi_id; /* User defined keymap entries have negative ids */
502  }
503 }
504 
505 /* always add item */
507  wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
508 {
509  wmKeyMapItem *kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
510 
511  BLI_addtail(&keymap->items, kmi);
512  BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
513 
514  keymap_event_set(kmi, type, val, modifier, keymodifier);
516 
517  keymap_item_set_id(keymap, kmi);
518 
519  WM_keyconfig_update_tag(keymap, kmi);
520 
521  return kmi;
522 }
523 
525 {
526  wmKeyMapItem *kmi_dst = wm_keymap_item_copy(kmi_src);
527 
528  BLI_addtail(&keymap->items, kmi_dst);
529 
530  keymap_item_set_id(keymap, kmi_dst);
531 
532  WM_keyconfig_update_tag(keymap, kmi_dst);
533 
534  return kmi_dst;
535 }
536 
538 {
539  if (BLI_findindex(&keymap->items, kmi) != -1) {
540  if (kmi->ptr) {
542  MEM_freeN(kmi->ptr);
543  }
544  BLI_freelinkN(&keymap->items, kmi);
545 
546  WM_keyconfig_update_tag(keymap, NULL);
547  return true;
548  }
549  return false;
550 }
551 
554 /* -------------------------------------------------------------------- */
563 static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap)
564 {
565  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &addonmap->items) {
566  wmKeyMapItem *kmi_new = wm_keymap_item_copy(kmi);
567  keymap_item_set_id(keymap, kmi_new);
568  BLI_addhead(&keymap->items, kmi_new);
569  }
570 }
571 
573 {
574  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
575  if (wm_keymap_item_equals(kmi, needle)) {
576  return kmi;
577  }
578  }
579 
580  return NULL;
581 }
582 
584 {
585  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
586  if (wm_keymap_item_equals_result(kmi, needle)) {
587  return kmi;
588  }
589  }
590 
591  return NULL;
592 }
593 
594 static void wm_keymap_diff(
595  wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km)
596 {
597  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &from_km->items) {
598  wmKeyMapItem *to_kmi = WM_keymap_item_find_id(to_km, kmi->id);
599 
600  if (!to_kmi) {
601  /* remove item */
602  wmKeyMapDiffItem *kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
603  kmdi->remove_item = wm_keymap_item_copy(kmi);
604  BLI_addtail(&diff_km->diff_items, kmdi);
605  }
606  else if (to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) {
607  /* replace item */
608  wmKeyMapDiffItem *kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
609  kmdi->remove_item = wm_keymap_item_copy(kmi);
610  kmdi->add_item = wm_keymap_item_copy(to_kmi);
611  BLI_addtail(&diff_km->diff_items, kmdi);
612  }
613 
614  /* sync expanded flag back to original so we don't lose it on repatch */
615  if (to_kmi) {
616  wmKeyMapItem *orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id);
617 
618  if (!orig_kmi && addon_km) {
619  orig_kmi = wm_keymap_find_item_equals(addon_km, kmi);
620  }
621 
622  if (orig_kmi) {
623  orig_kmi->flag &= ~KMI_EXPANDED;
624  orig_kmi->flag |= (to_kmi->flag & KMI_EXPANDED);
625  }
626  }
627  }
628 
629  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &to_km->items) {
630  if (kmi->id < 0) {
631  /* add item */
632  wmKeyMapDiffItem *kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
633  kmdi->add_item = wm_keymap_item_copy(kmi);
634  BLI_addtail(&diff_km->diff_items, kmdi);
635  }
636  }
637 }
638 
639 static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
640 {
641  LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &diff_km->diff_items) {
642  /* find item to remove */
643  wmKeyMapItem *kmi_remove = NULL;
644  if (kmdi->remove_item) {
645  kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item);
646  if (!kmi_remove) {
647  kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item);
648  }
649  }
650 
651  /* add item */
652  if (kmdi->add_item) {
653  /* Do not re-add an already existing keymap item! See T42088. */
654  /* We seek only for exact copy here! See T42137. */
655  wmKeyMapItem *kmi_add = wm_keymap_find_item_equals(km, kmdi->add_item);
656 
673  if (kmi_add != NULL && kmi_add == kmi_remove) {
674  kmi_remove = NULL;
675  }
676  /* only if nothing to remove or item to remove found */
677  else if (!kmi_add && (!kmdi->remove_item || kmi_remove)) {
678  kmi_add = wm_keymap_item_copy(kmdi->add_item);
679  kmi_add->flag |= KMI_USER_MODIFIED;
680 
681  if (kmi_remove) {
682  kmi_add->flag &= ~KMI_EXPANDED;
683  kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED);
684  kmi_add->id = kmi_remove->id;
685  BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add);
686  }
687  else {
688  keymap_item_set_id(km, kmi_add);
689  BLI_addtail(&km->items, kmi_add);
690  }
691  }
692  }
693 
694  /* remove item */
695  if (kmi_remove) {
696  wm_keymap_item_free(kmi_remove);
697  BLI_freelinkN(&km->items, kmi_remove);
698  }
699  }
700 }
701 
703  wmKeyMap *defaultmap,
704  wmKeyMap *addonmap,
705  wmKeyMap *usermap)
706 {
707  int expanded = 0;
708 
709  /* remove previous keymap in list, we will replace it */
711  lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid);
712  if (km) {
713  expanded = (km->flag & (KEYMAP_EXPANDED | KEYMAP_CHILDREN_EXPANDED));
714  WM_keymap_clear(km);
715  BLI_freelinkN(lb, km);
716  }
717 
718  /* copy new keymap from an existing one */
719  if (usermap && !(usermap->flag & KEYMAP_DIFF)) {
720  /* for compatibility with old user preferences with non-diff
721  * keymaps we override the original entirely */
722 
723  km = wm_keymap_copy(usermap);
724 
725  /* try to find corresponding id's for items */
726  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
727  wmKeyMapItem *orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi);
728  if (!orig_kmi) {
729  orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi);
730  }
731 
732  if (orig_kmi) {
733  kmi->id = orig_kmi->id;
734  }
735  else {
736  kmi->id = -(km->kmi_id++);
737  }
738  }
739 
740  km->flag |= KEYMAP_UPDATE; /* update again to create diff */
741  }
742  else {
743  km = wm_keymap_copy(defaultmap);
744  }
745 
746  /* add addon keymap items */
747  if (addonmap) {
748  wm_keymap_addon_add(km, addonmap);
749  }
750 
751  /* tag as being user edited */
752  if (usermap) {
753  km->flag |= KEYMAP_USER_MODIFIED;
754  }
755  km->flag |= KEYMAP_USER | expanded;
756 
757  /* apply user changes of diff keymap */
758  if (usermap && (usermap->flag & KEYMAP_DIFF)) {
759  wm_keymap_patch(km, usermap);
760  }
761 
762  /* add to list */
763  BLI_addtail(lb, km);
764 
765  return km;
766 }
767 
769  wmKeyMap *defaultmap,
770  wmKeyMap *addonmap,
771  wmKeyMap *km)
772 {
773  /* create temporary default + addon keymap for diff */
774  wmKeyMap *origmap = defaultmap;
775 
776  if (addonmap) {
777  defaultmap = wm_keymap_copy(defaultmap);
778  wm_keymap_addon_add(defaultmap, addonmap);
779  }
780 
781  /* remove previous diff keymap in list, we will replace it */
782  wmKeyMap *prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid);
783  if (prevmap) {
784  WM_keymap_clear(prevmap);
785  BLI_freelinkN(lb, prevmap);
786  }
787 
788  /* create diff keymap */
789  wmKeyMap *diffmap = wm_keymap_new(km->idname, km->spaceid, km->regionid);
790  diffmap->flag |= KEYMAP_DIFF;
791  if (defaultmap->flag & KEYMAP_MODAL) {
792  diffmap->flag |= KEYMAP_MODAL;
793  }
794  wm_keymap_diff(diffmap, defaultmap, km, origmap, addonmap);
795 
796  /* add to list if not empty */
797  if (diffmap->diff_items.first) {
798  BLI_addtail(lb, diffmap);
799  }
800  else {
801  WM_keymap_clear(diffmap);
802  MEM_freeN(diffmap);
803  }
804 
805  /* free temporary default map */
806  if (addonmap) {
807  WM_keymap_clear(defaultmap);
808  MEM_freeN(defaultmap);
809  }
810 }
811 
814 /* -------------------------------------------------------------------- */
823 wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid)
824 {
825  LISTBASE_FOREACH (wmKeyMap *, km, lb) {
826  if (km->spaceid == spaceid && km->regionid == regionid) {
827  if (STREQLEN(idname, km->idname, KMAP_MAX_NAME)) {
828  return km;
829  }
830  }
831  }
832 
833  return NULL;
834 }
835 
837  const char *idname,
838  int spaceid,
839  int regionid)
840 {
841  LISTBASE_FOREACH (wmKeyMap *, km, lb) {
842  if (ELEM(km->spaceid, spaceid, SPACE_EMPTY) && km->regionid == regionid) {
843  if (STREQLEN(idname, km->idname, KMAP_MAX_NAME)) {
844  return km;
845  }
846  }
847  }
848 
849  return NULL;
850 }
851 
852 wmKeyMap *WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
853 {
854  wmKeyMap *km = WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
855 
856  if (km == NULL) {
857  km = wm_keymap_new(idname, spaceid, regionid);
858  BLI_addtail(&keyconf->keymaps, km);
859 
861  }
862 
863  return km;
864 }
865 
866 wmKeyMap *WM_keymap_find_all(wmWindowManager *wm, const char *idname, int spaceid, int regionid)
867 {
868  return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid);
869 }
870 
872  const char *idname,
873  int spaceid,
874  int regionid)
875 {
876  return WM_keymap_list_find_spaceid_or_empty(&wm->userconf->keymaps, idname, spaceid, regionid);
877 }
878 
881 /* -------------------------------------------------------------------- */
889  const char *idname,
890  const EnumPropertyItem *items)
891 {
892  wmKeyMap *km = WM_keymap_ensure(keyconf, idname, 0, 0);
893  km->flag |= KEYMAP_MODAL;
894 
895  /* init modal items from default config */
896  wmWindowManager *wm = G_MAIN->wm.first;
897  if (wm->defaultconf && wm->defaultconf != keyconf) {
898  wmKeyMap *defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0);
899 
900  if (defaultkm) {
901  km->modal_items = defaultkm->modal_items;
902  km->poll = defaultkm->poll;
903  km->poll_modal_item = defaultkm->poll_modal_item;
904  }
905  }
906 
907  if (items) {
908  km->modal_items = items;
909  }
910 
911  return km;
912 }
913 
914 wmKeyMap *WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
915 {
916  LISTBASE_FOREACH (wmKeyMap *, km, &keyconf->keymaps) {
917  if (km->flag & KEYMAP_MODAL) {
918  if (STREQLEN(idname, km->idname, KMAP_MAX_NAME)) {
919  return km;
920  }
921  }
922  }
923 
924  return NULL;
925 }
926 
928  wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value)
929 {
930  wmKeyMapItem *kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
931 
932  BLI_addtail(&km->items, kmi);
933  kmi->propvalue = value;
934 
935  keymap_event_set(kmi, type, val, modifier, keymodifier);
936 
937  keymap_item_set_id(km, kmi);
938 
939  WM_keyconfig_update_tag(km, kmi);
940 
941  return kmi;
942 }
943 
945  wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value)
946 {
947  wmKeyMapItem *kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
948 
949  BLI_addtail(&km->items, kmi);
950  BLI_strncpy(kmi->propvalue_str, value, sizeof(kmi->propvalue_str));
951 
952  keymap_event_set(kmi, type, val, modifier, keymodifier);
953 
954  keymap_item_set_id(km, kmi);
955 
956  WM_keyconfig_update_tag(km, kmi);
957 
958  return kmi;
959 }
960 
962  const wmKeyMapItem *kmi,
963  const int propvalue)
964 {
965  if (km->flag & KEYMAP_MODAL) {
966  kmi = kmi ? kmi->next : km->items.first;
967  for (; kmi; kmi = kmi->next) {
968  if (kmi->propvalue == propvalue) {
969  return kmi;
970  }
971  }
972  }
973  else {
974  BLI_assert(!"called with non modal keymap");
975  }
976 
977  return NULL;
978 }
979 
980 const wmKeyMapItem *WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int propvalue)
981 {
982  return wm_modalkeymap_find_propvalue_iter(km, NULL, propvalue);
983 }
984 
985 void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
986 {
987  wmOperatorType *ot = WM_operatortype_find(opname, 0);
988 
989  if (ot) {
990  ot->modalkeymap = km;
991  }
992  else {
993  CLOG_ERROR(WM_LOG_KEYMAPS, "unknown operator '%s'", opname);
994  }
995 }
996 
998 {
999  /* here we convert propvalue string values delayed, due to python keymaps
1000  * being created before the actual modal keymaps, so no modal_items */
1001 
1002  if (km && (km->flag & KEYMAP_MODAL) && !km->modal_items) {
1003  if (wm->defaultconf == NULL) {
1004  return;
1005  }
1006 
1007  wmKeyMap *defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0);
1008  if (!defaultkm) {
1009  return;
1010  }
1011 
1012  km->modal_items = defaultkm->modal_items;
1013  km->poll = defaultkm->poll;
1014  km->poll_modal_item = defaultkm->poll_modal_item;
1015 
1016  if (km->modal_items) {
1017  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
1018  if (kmi->propvalue_str[0]) {
1019  int propvalue;
1020  if (RNA_enum_value_from_id(km->modal_items, kmi->propvalue_str, &propvalue)) {
1021  kmi->propvalue = propvalue;
1022  }
1023  kmi->propvalue_str[0] = '\0';
1024  }
1025  }
1026  }
1027  }
1028 }
1029 
1032 /* -------------------------------------------------------------------- */
1036 static const char *key_event_glyph_or_text(const int font_id,
1037  const char *text,
1038  const char *single_glyph)
1039 {
1040  BLI_assert(single_glyph == NULL || (BLI_strlen_utf8(single_glyph) == 1));
1041  return (single_glyph && BLF_has_glyph(font_id, BLI_str_utf8_as_unicode(single_glyph))) ?
1042  single_glyph :
1043  text;
1044 }
1045 
1046 const char *WM_key_event_string(const short type, const bool compact)
1047 {
1048  if (compact) {
1049  /* String storing a single unicode character or NULL. */
1050  const char *single_glyph = NULL;
1051  int font_id = BLF_default();
1052  const enum {
1053  UNIX,
1054  MACOS,
1055  MSWIN,
1056  } platform =
1057 
1058 #if defined(__APPLE__)
1059  MACOS
1060 #elif defined(_WIN32)
1061  MSWIN
1062 #else
1063  UNIX
1064 #endif
1065  ;
1066 
1067  switch (type) {
1068  case EVT_LEFTSHIFTKEY:
1069  case EVT_RIGHTSHIFTKEY: {
1070  if (platform == MACOS) {
1071  single_glyph = "\xe2\x87\xa7";
1072  }
1073  return key_event_glyph_or_text(
1074  font_id, CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Shift"), single_glyph);
1075  }
1076  case EVT_LEFTCTRLKEY:
1077  case EVT_RIGHTCTRLKEY:
1078  if (platform == MACOS) {
1079  return key_event_glyph_or_text(font_id, "^", "\xe2\x8c\x83");
1080  }
1081  return IFACE_("Ctrl");
1082  case EVT_LEFTALTKEY:
1083  case EVT_RIGHTALTKEY: {
1084  if (platform == MACOS) {
1085  /* Option symbol on Mac keyboard. */
1086  single_glyph = "\xe2\x8c\xa5";
1087  }
1088  return key_event_glyph_or_text(font_id, IFACE_("Alt"), single_glyph);
1089  }
1090  case EVT_OSKEY: {
1091  if (platform == MACOS) {
1092  return key_event_glyph_or_text(font_id, IFACE_("Cmd"), "\xe2\x8c\x98");
1093  }
1094  if (platform == MSWIN) {
1095  return key_event_glyph_or_text(font_id, IFACE_("Win"), "\xe2\x9d\x96");
1096  }
1097  return IFACE_("OS");
1098  } break;
1099  case EVT_TABKEY:
1100  return key_event_glyph_or_text(font_id, IFACE_("Tab"), "\xe2\xad\xbe");
1101  case EVT_BACKSPACEKEY:
1102  return key_event_glyph_or_text(font_id, IFACE_("Bksp"), "\xe2\x8c\xab");
1103  case EVT_ESCKEY:
1104  if (platform == MACOS) {
1105  single_glyph = "\xe2\x8e\x8b";
1106  }
1107  return key_event_glyph_or_text(font_id, IFACE_("Esc"), single_glyph);
1108  case EVT_RETKEY:
1109  return key_event_glyph_or_text(font_id, IFACE_("Enter"), "\xe2\x86\xb5");
1110  case EVT_SPACEKEY:
1111  return key_event_glyph_or_text(font_id, IFACE_("Space"), "\xe2\x90\xa3");
1112  case EVT_LEFTARROWKEY:
1113  return key_event_glyph_or_text(font_id, IFACE_("Left"), "\xe2\x86\x90");
1114  case EVT_UPARROWKEY:
1115  return key_event_glyph_or_text(font_id, IFACE_("Up"), "\xe2\x86\x91");
1116  case EVT_RIGHTARROWKEY:
1117  return key_event_glyph_or_text(font_id, IFACE_("Right"), "\xe2\x86\x92");
1118  case EVT_DOWNARROWKEY:
1119  return key_event_glyph_or_text(font_id, IFACE_("Down"), "\xe2\x86\x93");
1120  }
1121  }
1122 
1123  const EnumPropertyItem *it;
1124  const int i = RNA_enum_from_value(rna_enum_event_type_items, (int)type);
1125 
1126  if (i == -1) {
1127  return "";
1128  }
1129  it = &rna_enum_event_type_items[i];
1130 
1131  /* We first try enum items' description (abused as shortname here),
1132  * and fall back to usual name if empty. */
1133  if (compact && it->description[0]) {
1134  /* XXX No context for enum descriptions... In practice shall not be an issue though. */
1135  return IFACE_(it->description);
1136  }
1137 
1139 }
1140 
1141 /* TODO: also support (some) value, like e.g. double-click? */
1142 int WM_keymap_item_raw_to_string(const short shift,
1143  const short ctrl,
1144  const short alt,
1145  const short oskey,
1146  const short keymodifier,
1147  const short val,
1148  const short type,
1149  const bool compact,
1150  char *result,
1151  const int result_len)
1152 {
1153 #define ADD_SEP \
1154  if (p != buf) { \
1155  *p++ = ' '; \
1156  } \
1157  (void)0
1158 
1159  char buf[128];
1160  char *p = buf;
1161 
1162  buf[0] = '\0';
1163 
1164  /* TODO: support order (KM_SHIFT vs. KM_SHIFT2) ? */
1165  if (shift == KM_ANY && ctrl == KM_ANY && alt == KM_ANY && oskey == KM_ANY) {
1166  /* Don't show anything for any mapping. */
1167  }
1168  else {
1169  if (shift) {
1170  ADD_SEP;
1172  }
1173 
1174  if (ctrl) {
1175  ADD_SEP;
1177  }
1178 
1179  if (alt) {
1180  ADD_SEP;
1182  }
1183 
1184  if (oskey) {
1185  ADD_SEP;
1187  }
1188  }
1189 
1190  if (keymodifier) {
1191  ADD_SEP;
1192  p += BLI_strcpy_rlen(p, WM_key_event_string(keymodifier, compact));
1193  }
1194 
1195  if (type) {
1196  ADD_SEP;
1197  if (val == KM_DBL_CLICK) {
1198  p += BLI_strcpy_rlen(p, IFACE_("dbl-"));
1199  }
1200  p += BLI_strcpy_rlen(p, WM_key_event_string(type, compact));
1201  }
1202 
1203  /* We assume size of buf is enough to always store any possible shortcut,
1204  * but let's add a debug check about it! */
1205  BLI_assert(p - buf < sizeof(buf));
1206 
1207  /* We need utf8 here, otherwise we may 'cut' some unicode chars like arrows... */
1208  return BLI_strncpy_utf8_rlen(result, buf, result_len);
1209 
1210 #undef ADD_SEP
1211 }
1212 
1214  const bool compact,
1215  char *result,
1216  const int result_len)
1217 {
1218  return WM_keymap_item_raw_to_string(kmi->shift,
1219  kmi->ctrl,
1220  kmi->alt,
1221  kmi->oskey,
1222  kmi->keymodifier,
1223  kmi->val,
1224  kmi->type,
1225  compact,
1226  result,
1227  result_len);
1228 }
1229 
1231  const int propvalue,
1232  const bool compact,
1233  char *result,
1234  const int result_len)
1235 {
1236  int totlen = 0;
1237  bool add_sep = false;
1238 
1239  if (km) {
1240  const wmKeyMapItem *kmi;
1241 
1242  /* Find all shortcuts related to that propvalue! */
1243  for (kmi = WM_modalkeymap_find_propvalue(km, propvalue); kmi && totlen < (result_len - 2);
1244  kmi = wm_modalkeymap_find_propvalue_iter(km, kmi, propvalue)) {
1245  if (add_sep) {
1246  result[totlen++] = '/';
1247  result[totlen] = '\0';
1248  }
1249  else {
1250  add_sep = true;
1251  }
1252  totlen += WM_keymap_item_to_string(kmi, compact, &result[totlen], result_len - totlen);
1253  }
1254  }
1255 
1256  return totlen;
1257 }
1258 
1260  const int propvalue,
1261  const bool compact,
1262  char *result,
1263  const int result_len)
1264 {
1265  wmWindowManager *wm = G_MAIN->wm.first;
1266  wmKeyMap *keymap = WM_keymap_active(wm, ot->modalkeymap);
1267  return WM_modalkeymap_items_to_string(keymap, propvalue, compact, result, result_len);
1268 }
1269 
1271  const int propvalue,
1272  const bool compact,
1273  const int max_len,
1274  int *r_available_len,
1275  char **r_result)
1276 {
1277  char *ret = *r_result;
1278 
1279  if (*r_available_len > 1) {
1281  ot, propvalue, compact, ret, min_ii(*r_available_len, max_len)) +
1282  1;
1283 
1284  *r_available_len -= used_len;
1285  *r_result += used_len;
1286  if (*r_available_len == 0) {
1287  (*r_result)--; /* So that *result keeps pointing on a valid char, we'll stay on it anyway. */
1288  }
1289  }
1290  else {
1291  *ret = '\0';
1292  }
1293 
1294  return ret;
1295 }
1296 
1300  const char *opname,
1301  IDProperty *properties,
1302  const bool is_strict,
1303  const struct wmKeyMapItemFind_Params *params)
1304 {
1305  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
1306  /* skip disabled keymap items [T38447] */
1307  if (kmi->flag & KMI_INACTIVE) {
1308  continue;
1309  }
1310 
1311  bool kmi_match = false;
1312 
1313  if (STREQ(kmi->idname, opname)) {
1314  if (properties) {
1315  /* example of debugging keymaps */
1316 #if 0
1317  if (kmi->ptr) {
1318  if (STREQ("MESH_OT_rip_move", opname)) {
1319  printf("OPERATOR\n");
1320  IDP_print(properties);
1321  printf("KEYMAP\n");
1322  IDP_print(kmi->ptr->data);
1323  }
1324  }
1325 #endif
1326 
1327  if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) {
1328  kmi_match = true;
1329  }
1330  /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
1331  else if (G.debug & G_DEBUG_WM) {
1332  if (is_strict && kmi->ptr) {
1333  wmOperatorType *ot = WM_operatortype_find(opname, true);
1334  if (ot) {
1335  /* make a copy of the properties and set unset ones to their default values. */
1336  PointerRNA opptr;
1337  IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data);
1338 
1339  RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
1340  WM_operator_properties_default(&opptr, true);
1341 
1342  if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) {
1343  char kmi_str[128];
1344  WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str));
1345  /* NOTE: given properties could come from other things than menu entry. */
1346  printf(
1347  "%s: Some set values in menu entry match default op values, "
1348  "this might not be desired!\n",
1349  opname);
1350  printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str);
1351 #ifndef NDEBUG
1352 # ifdef WITH_PYTHON
1353  printf("OPERATOR\n");
1354  IDP_print(properties);
1355  printf("KEYMAP\n");
1356  IDP_print(kmi->ptr->data);
1357 # endif
1358 #endif
1359  printf("\n");
1360  }
1361 
1362  IDP_FreeProperty(properties_default);
1363  }
1364  }
1365  }
1366  }
1367  else {
1368  kmi_match = true;
1369  }
1370 
1371  if (kmi_match) {
1372  if ((params == NULL) || params->filter_fn(keymap, kmi, params->user_data)) {
1373  return kmi;
1374  }
1375  }
1376  }
1377  }
1378  return NULL;
1379 }
1380 
1382  ListBase *handlers,
1383  const char *opname,
1384  int UNUSED(opcontext),
1385  IDProperty *properties,
1386  const bool is_strict,
1387  const struct wmKeyMapItemFind_Params *params,
1388  wmKeyMap **r_keymap)
1389 {
1391 
1392  /* find keymap item in handlers */
1393  LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
1394  if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) {
1395  wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base;
1396  wmKeyMap *keymap = WM_event_get_keymap_from_handler(wm, handler);
1397  if (keymap && WM_keymap_poll((bContext *)C, keymap)) {
1399  keymap, opname, properties, is_strict, params);
1400  if (kmi != NULL) {
1401  if (r_keymap) {
1402  *r_keymap = keymap;
1403  }
1404  return kmi;
1405  }
1406  }
1407  }
1408  }
1409  /* ensure un-initialized keymap is never used */
1410  if (r_keymap) {
1411  *r_keymap = NULL;
1412  }
1413  return NULL;
1414 }
1415 
1417  const char *opname,
1418  int opcontext,
1419  IDProperty *properties,
1420  const bool is_strict,
1421  const struct wmKeyMapItemFind_Params *params,
1422  wmKeyMap **r_keymap)
1423 {
1424  wmWindow *win = CTX_wm_window(C);
1425  ScrArea *area = CTX_wm_area(C);
1426  ARegion *region = CTX_wm_region(C);
1427  wmKeyMapItem *found = NULL;
1428 
1429  /* look into multiple handler lists to find the item */
1430  if (win) {
1432  C, &win->modalhandlers, opname, opcontext, properties, is_strict, params, r_keymap);
1433  if (found == NULL) {
1435  C, &win->handlers, opname, opcontext, properties, is_strict, params, r_keymap);
1436  }
1437  }
1438 
1439  if (area && found == NULL) {
1441  C, &area->handlers, opname, opcontext, properties, is_strict, params, r_keymap);
1442  }
1443 
1444  if (found == NULL) {
1446  if (area) {
1447  if (!(region && region->regiontype == RGN_TYPE_WINDOW)) {
1449  }
1450 
1451  if (region) {
1453  C, &region->handlers, opname, opcontext, properties, is_strict, params, r_keymap);
1454  }
1455  }
1456  }
1458  if (!(region && region->regiontype == RGN_TYPE_CHANNELS)) {
1460  }
1461 
1462  if (region) {
1464  C, &region->handlers, opname, opcontext, properties, is_strict, params, r_keymap);
1465  }
1466  }
1468  if (!(region && region->regiontype == RGN_TYPE_PREVIEW)) {
1470  }
1471 
1472  if (region) {
1474  C, &region->handlers, opname, opcontext, properties, is_strict, params, r_keymap);
1475  }
1476  }
1477  else {
1478  if (region) {
1480  C, &region->handlers, opname, opcontext, properties, is_strict, params, r_keymap);
1481  }
1482  }
1483  }
1484 
1485  return found;
1486 }
1487 
1489  const char *opname,
1490  int opcontext,
1491  IDProperty *properties,
1492  bool is_strict,
1493  const struct wmKeyMapItemFind_Params *params,
1494  wmKeyMap **r_keymap)
1495 {
1496  /* XXX Hack! Macro operators in menu entry have their whole props defined,
1497  * which is not the case for relevant keymap entries.
1498  * Could be good to check and harmonize this,
1499  * but for now always compare non-strict in this case. */
1500  wmOperatorType *ot = WM_operatortype_find(opname, true);
1501  if (ot) {
1502  is_strict = is_strict && ((ot->flag & OPTYPE_MACRO) == 0);
1503  }
1504 
1506  C, opname, opcontext, properties, is_strict, params, r_keymap);
1507 
1508  /* This block is *only* useful in one case: when op uses an enum menu in its prop member
1509  * (then, we want to rerun a comparison with that 'prop' unset). Note this remains brittle,
1510  * since now any enum prop may be used in UI (specified by name), ot->prop is not so much used...
1511  * Otherwise:
1512  * * If non-strict, unset properties always match set ones in IDP_EqualsProperties_ex.
1513  * * If strict, unset properties never match set ones in IDP_EqualsProperties_ex,
1514  * and we do not want that to change (else we get things like T41757)!
1515  * ...so in either case, re-running a comparison with unset props set to default is useless.
1516  */
1517  if (!found && properties) {
1518  if (ot && ot->prop) { /* XXX Shall we also check ot->prop is actually an enum? */
1519  /* make a copy of the properties and unset the 'ot->prop' one if set. */
1520  PointerRNA opptr;
1521  IDProperty *properties_temp = IDP_CopyProperty(properties);
1522 
1523  RNA_pointer_create(NULL, ot->srna, properties_temp, &opptr);
1524 
1525  if (RNA_property_is_set(&opptr, ot->prop)) {
1526  /* For operator that has enum menu,
1527  * unset it so its value does not affect comparison result. */
1528  RNA_property_unset(&opptr, ot->prop);
1529 
1530  found = wm_keymap_item_find_props(
1531  C, opname, opcontext, properties_temp, is_strict, params, r_keymap);
1532  }
1533 
1534  IDP_FreeProperty(properties_temp);
1535  }
1536  }
1537 
1538  /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
1539  if (G.debug & G_DEBUG_WM) {
1540  if (!found && is_strict && properties) {
1541  if (ot) {
1542  /* make a copy of the properties and set unset ones to their default values. */
1543  PointerRNA opptr;
1544  IDProperty *properties_default = IDP_CopyProperty(properties);
1545 
1546  RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
1547  WM_operator_properties_default(&opptr, true);
1548 
1549  wmKeyMap *km;
1551  C, opname, opcontext, properties_default, is_strict, params, &km);
1552  if (kmi) {
1553  char kmi_str[128];
1554  WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str));
1555  printf(
1556  "%s: Some set values in keymap entry match default op values, "
1557  "this might not be desired!\n",
1558  opname);
1559  printf("\tkm: '%s', kmi: '%s'\n", km->idname, kmi_str);
1560 #ifndef NDEBUG
1561 # ifdef WITH_PYTHON
1562  printf("OPERATOR\n");
1563  IDP_print(properties);
1564  printf("KEYMAP\n");
1565  IDP_print(kmi->ptr->data);
1566 # endif
1567 #endif
1568  printf("\n");
1569  }
1570 
1571  IDP_FreeProperty(properties_default);
1572  }
1573  }
1574  }
1575 
1576  return found;
1577 }
1578 
1579 static bool kmi_filter_is_visible(const wmKeyMap *UNUSED(km),
1580  const wmKeyMapItem *kmi,
1581  void *UNUSED(user_data))
1582 {
1583  return ((WM_key_event_string(kmi->type, false)[0] != '\0') &&
1584  (IS_EVENT_ACTIONZONE(kmi->type) == false));
1585 }
1586 
1588  const char *opname,
1589  int opcontext,
1590  IDProperty *properties,
1591  const bool is_strict,
1592  char *result,
1593  const int result_len)
1594 {
1596  opname,
1597  opcontext,
1598  properties,
1599  is_strict,
1600  &(struct wmKeyMapItemFind_Params){
1601  .filter_fn = kmi_filter_is_visible,
1602  .user_data = NULL,
1603  },
1604  NULL);
1605  if (kmi) {
1606  WM_keymap_item_to_string(kmi, false, result, result_len);
1607  return result;
1608  }
1609 
1610  return NULL;
1611 }
1612 
1614  const wmKeyMapItem *kmi,
1615  void *user_data)
1616 {
1617  short *mask_pair = user_data;
1618  return ((WM_event_type_mask_test(kmi->type, mask_pair[0]) == true) &&
1619  (WM_event_type_mask_test(kmi->type, mask_pair[1]) == false) &&
1620  kmi_filter_is_visible(km, kmi, user_data));
1621 }
1622 
1628  const char *opname,
1629  int opcontext,
1630  IDProperty *properties,
1631  const short include_mask,
1632  const short exclude_mask,
1633  wmKeyMap **r_keymap)
1634 {
1635  short user_data_mask[2] = {include_mask, exclude_mask};
1636  bool use_mask = (include_mask != EVT_TYPE_MASK_ALL) || (exclude_mask != 0);
1637  return wm_keymap_item_find(
1638  C,
1639  opname,
1640  opcontext,
1641  properties,
1642  true,
1643  &(struct wmKeyMapItemFind_Params){
1644  .filter_fn = use_mask ? kmi_filter_is_visible_type_mask : kmi_filter_is_visible,
1645  .user_data = use_mask ? user_data_mask : NULL,
1646  },
1647  r_keymap);
1648 }
1649 
1651  const char *opname,
1652  IDProperty *properties,
1653  const short include_mask,
1654  const short exclude_mask)
1655 {
1656  short user_data_mask[2] = {include_mask, exclude_mask};
1657  bool use_mask = (include_mask != EVT_TYPE_MASK_ALL) || (exclude_mask != 0);
1659  keymap,
1660  opname,
1661  properties,
1662  true,
1663  &(struct wmKeyMapItemFind_Params){
1664  .filter_fn = use_mask ? kmi_filter_is_visible_type_mask : kmi_filter_is_visible,
1665  .user_data = use_mask ? user_data_mask : NULL,
1666  });
1667 }
1668 
1670 {
1671  if (k1->flag & KMI_INACTIVE || k2->flag & KMI_INACTIVE) {
1672  return 0;
1673  }
1674 
1675  /* take event mapping into account */
1676  int k1type = WM_userdef_event_map(k1->type);
1677  int k2type = WM_userdef_event_map(k2->type);
1678 
1679  if (k1type != KM_ANY && k2type != KM_ANY && k1type != k2type) {
1680  return 0;
1681  }
1682 
1683  if (k1->val != KM_ANY && k2->val != KM_ANY) {
1684  /* take click, press, release conflict into account */
1685  if (k1->val == KM_CLICK && ELEM(k2->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0) {
1686  return 0;
1687  }
1688  if (k2->val == KM_CLICK && ELEM(k1->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0) {
1689  return 0;
1690  }
1691  if (k1->val != k2->val) {
1692  return 0;
1693  }
1694  }
1695 
1696  if (k1->shift != KM_ANY && k2->shift != KM_ANY && k1->shift != k2->shift) {
1697  return 0;
1698  }
1699 
1700  if (k1->ctrl != KM_ANY && k2->ctrl != KM_ANY && k1->ctrl != k2->ctrl) {
1701  return 0;
1702  }
1703 
1704  if (k1->alt != KM_ANY && k2->alt != KM_ANY && k1->alt != k2->alt) {
1705  return 0;
1706  }
1707 
1708  if (k1->oskey != KM_ANY && k2->oskey != KM_ANY && k1->oskey != k2->oskey) {
1709  return 0;
1710  }
1711 
1712  if (k1->keymodifier != k2->keymodifier) {
1713  return 0;
1714  }
1715 
1716  return 1;
1717 }
1718 
1721 /* -------------------------------------------------------------------- */
1729 /* so operator removal can trigger update */
1730 enum {
1732 
1733  /* ensure all wmKeyMap have their operator types validated after removing an operator */
1735 };
1736 
1737 static char wm_keymap_update_flag = 0;
1738 
1740 {
1741  /* quick tag to do delayed keymap updates */
1743 
1744  if (keymap) {
1745  keymap->flag |= KEYMAP_UPDATE;
1746  }
1747  if (kmi) {
1748  kmi->flag |= KMI_UPDATE;
1749  }
1750 }
1751 
1753 {
1755 }
1756 
1758 {
1759  int update = (km->flag & KEYMAP_UPDATE);
1760  km->flag &= ~KEYMAP_UPDATE;
1761 
1762  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
1763  update = update || (kmi->flag & KMI_UPDATE);
1764  kmi->flag &= ~KMI_UPDATE;
1765  }
1766 
1767  return (update != 0);
1768 }
1769 
1771 {
1772  wmKeyConfig *keyconf = WM_keyconfig_active(wm);
1773  wmKeyMap *keymap = WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid);
1774  if (!keymap && wm->defaultconf) {
1775  keymap = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid);
1776  }
1777 
1778  return keymap;
1779 }
1780 
1782 {
1783  bool compat_update = false;
1784 
1785  if (wm_keymap_update_flag == 0) {
1786  return;
1787  }
1788 
1790  /* an operatortype has been removed, this wont happen often
1791  * but when it does we have to check _every_ keymap item */
1792  ListBase *keymaps_lb[] = {
1793  &U.user_keymaps,
1794  &wm->userconf->keymaps,
1795  &wm->defaultconf->keymaps,
1796  &wm->addonconf->keymaps,
1797  NULL,
1798  };
1799 
1800  int i;
1801 
1802  for (i = 0; keymaps_lb[i]; i++) {
1804  }
1805 
1806  LISTBASE_FOREACH (wmKeyConfig *, kc, &wm->keyconfigs) {
1808  }
1809 
1811  }
1812 
1814  /* update operator properties for non-modal user keymaps */
1815  LISTBASE_FOREACH (wmKeyMap *, km, &U.user_keymaps) {
1816  if ((km->flag & KEYMAP_MODAL) == 0) {
1817  LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
1818  if (kmdi->add_item) {
1819  wm_keymap_item_properties_set(kmdi->add_item);
1820  }
1821  if (kmdi->remove_item) {
1822  wm_keymap_item_properties_set(kmdi->remove_item);
1823  }
1824  }
1825 
1826  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
1828  }
1829  }
1830  }
1831 
1832  /* update U.user_keymaps with user key configuration changes */
1833  LISTBASE_FOREACH (wmKeyMap *, km, &wm->userconf->keymaps) {
1834  /* only diff if the user keymap was modified */
1836  /* find keymaps */
1837  wmKeyMap *defaultmap = wm_keymap_preset(wm, km);
1838  wmKeyMap *addonmap = WM_keymap_list_find(
1839  &wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
1840 
1841  /* diff */
1842  if (defaultmap) {
1843  wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km);
1844  }
1845  }
1846  }
1847 
1848  /* create user key configuration from preset + addon + user preferences */
1849  LISTBASE_FOREACH (wmKeyMap *, km, &wm->defaultconf->keymaps) {
1850  /* find keymaps */
1851  wmKeyMap *defaultmap = wm_keymap_preset(wm, km);
1852  wmKeyMap *addonmap = WM_keymap_list_find(
1853  &wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
1854  wmKeyMap *usermap = WM_keymap_list_find(
1855  &U.user_keymaps, km->idname, km->spaceid, km->regionid);
1856 
1857  /* For now only the default map defines modal key-maps,
1858  * if we support modal keymaps for 'addonmap', these will need to be enabled too. */
1859  wm_user_modal_keymap_set_items(wm, defaultmap);
1860 
1861  /* add */
1863  &wm->userconf->keymaps, defaultmap, addonmap, usermap);
1864 
1865  if (kmn) {
1866  kmn->modal_items = km->modal_items;
1867  kmn->poll = km->poll;
1868  kmn->poll_modal_item = km->poll_modal_item;
1869  }
1870 
1871  /* in case of old non-diff keymaps, force extra update to create diffs */
1872  compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF));
1873  }
1874 
1876  }
1877 
1879 
1880  if (compat_update) {
1882  WM_keyconfig_update(wm);
1883  }
1884 }
1885 
1888 /* -------------------------------------------------------------------- */
1896 {
1897  if (!keymap) {
1898  return NULL;
1899  }
1900 
1901  /* first user defined keymaps */
1903  &wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
1904 
1905  if (km) {
1906  return km;
1907  }
1908 
1909  return keymap;
1910 }
1911 
1914 /* -------------------------------------------------------------------- */
1921 {
1922  if (!keymap) {
1923  return;
1924  }
1925 
1926  /* construct default keymap from preset + addons */
1927  wmKeyMap *defaultmap = wm_keymap_preset(wm, keymap);
1928  wmKeyMap *addonmap = WM_keymap_list_find(
1929  &wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
1930 
1931  if (addonmap) {
1932  defaultmap = wm_keymap_copy(defaultmap);
1933  wm_keymap_addon_add(defaultmap, addonmap);
1934  }
1935 
1936  /* find original item */
1937  wmKeyMapItem *orig = WM_keymap_item_find_id(defaultmap, kmi->id);
1938 
1939  if (orig) {
1940  /* restore to original */
1941  if (!STREQ(orig->idname, kmi->idname)) {
1942  BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
1944  }
1945 
1946  if (orig->properties) {
1947  if (kmi->properties) {
1949  kmi->properties = NULL;
1950  }
1951 
1952  kmi->properties = IDP_CopyProperty(orig->properties);
1953  kmi->ptr->data = kmi->properties;
1954  }
1955 
1956  kmi->propvalue = orig->propvalue;
1957  kmi->type = orig->type;
1958  kmi->val = orig->val;
1959  kmi->shift = orig->shift;
1960  kmi->ctrl = orig->ctrl;
1961  kmi->alt = orig->alt;
1962  kmi->oskey = orig->oskey;
1963  kmi->keymodifier = orig->keymodifier;
1964  kmi->maptype = orig->maptype;
1965  kmi->flag = (kmi->flag & ~KMI_REPEAT_IGNORE) | (orig->flag & KMI_REPEAT_IGNORE);
1966 
1967  WM_keyconfig_update_tag(keymap, kmi);
1968  }
1969 
1970  /* free temporary keymap */
1971  if (addonmap) {
1972  WM_keymap_clear(defaultmap);
1973  MEM_freeN(defaultmap);
1974  }
1975 }
1976 
1978 {
1979  /* remove keymap from U.user_keymaps and update */
1980  wmKeyMap *usermap = WM_keymap_list_find(
1981  &U.user_keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
1982 
1983  if (usermap) {
1984  WM_keymap_clear(usermap);
1985  BLI_freelinkN(&U.user_keymaps, usermap);
1986 
1988  WM_keyconfig_update(wm);
1989  }
1990 }
1991 
1993 {
1994  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
1995  if (kmi->id == id) {
1996  return kmi;
1997  }
1998  }
1999 
2000  return NULL;
2001 }
2002 
2003 const char *WM_bool_as_string(bool test)
2004 {
2005  return test ? IFACE_("ON") : IFACE_("OFF");
2006 }
2007 
struct WorkSpace * CTX_wm_workspace(const bContext *C)
Definition: context.c:704
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
#define G_MAIN
Definition: BKE_global.h:232
@ G_DEBUG_WM
Definition: BKE_global.h:138
void IDP_print(const struct IDProperty *prop)
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1040
bool IDP_EqualsProperties_ex(struct IDProperty *prop1, struct IDProperty *prop2, const bool is_strict) ATTR_WARN_UNUSED_RESULT
Definition: idprop.c:788
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
struct ARegion * BKE_area_find_region_type(const struct ScrArea *area, int type)
bool BKE_workspace_owner_id_check(const struct WorkSpace *workspace, const char *owner_id) ATTR_NONNULL()
int BLF_default(void)
Definition: blf_default.c:55
bool BLF_has_glyph(int fontid, unsigned int unicode)
Definition: blf.c:144
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
MINLINE int min_ii(int a, int b)
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:201
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL()
Definition: string_utf8.c:357
unsigned int BLI_str_utf8_as_unicode(const char *p) ATTR_NONNULL()
Definition: string_utf8.c:533
size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string_utf8.c:274
#define STREQLEN(a, b, n)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define LIKELY(x)
#define BLT_I18NCONTEXT_ID_WINDOWMANAGER
#define CTX_IFACE_(context, msgid)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_UI_EVENTS
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:203
Object is a sort of wrapper for general info.
@ RGN_TYPE_CHANNELS
@ RGN_TYPE_WINDOW
@ RGN_TYPE_PREVIEW
@ SPACE_EMPTY
#define OP_MAX_TYPENAME
#define KMAP_MAX_NAME
@ KEYMAP_USER_MODIFIED
@ KEYMAP_CHILDREN_EXPANDED
@ KMI_REPEAT_IGNORE
@ KMI_USER_MODIFIED
@ WM_KEYCONFIG_IS_INIT
@ KMI_TYPE_TEXTINPUT
@ KMI_TYPE_KEYBOARD
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
@ RNA_EQ_UNSET_MATCH_NONE
Definition: RNA_access.h:1455
#define C
Definition: RandGen.cpp:39
#define KM_MOD_SECOND
Definition: WM_types.h:234
@ OPTYPE_MACRO
Definition: WM_types.h:158
#define KM_SHIFT2
Definition: WM_types.h:226
#define KM_CLICK
Definition: WM_types.h:244
#define KM_OSKEY2
Definition: WM_types.h:229
#define KM_SHIFT
Definition: WM_types.h:221
#define KM_ANY
Definition: WM_types.h:240
@ WM_OP_INVOKE_REGION_WIN
Definition: WM_types.h:198
@ WM_OP_EXEC_REGION_WIN
Definition: WM_types.h:205
@ WM_OP_EXEC_REGION_PREVIEW
Definition: WM_types.h:207
@ WM_OP_INVOKE_REGION_PREVIEW
Definition: WM_types.h:200
@ WM_OP_EXEC_REGION_CHANNELS
Definition: WM_types.h:206
@ WM_OP_INVOKE_REGION_CHANNELS
Definition: WM_types.h:199
#define KM_CTRL2
Definition: WM_types.h:227
struct CLG_LogRef * WM_LOG_KEYMAPS
#define KM_PRESS
Definition: WM_types.h:242
#define KM_TEXTINPUT
Definition: WM_types.h:237
#define KM_MOD_FIRST
Definition: WM_types.h:233
#define KM_CTRL
Definition: WM_types.h:222
#define KM_ALT2
Definition: WM_types.h:228
#define KM_DBL_CLICK
Definition: WM_types.h:245
#define KM_ALT
Definition: WM_types.h:223
#define KM_OSKEY
Definition: WM_types.h:224
#define KM_RELEASE
Definition: WM_types.h:243
unsigned int U
Definition: btGjkEpa3.h:78
void * user_data
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
static void update(bNodeTree *ntree)
return ret
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
bool RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value)
Definition: rna_access.c:6474
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
Definition: rna_access.c:1902
const char * RNA_struct_state_owner_get(void)
Definition: rna_access.c:8198
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6665
bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACompareMode mode)
const EnumPropertyItem rna_enum_event_type_items[]
Definition: rna_wm.c:146
ListBase handlers
short regiontype
const char * name
Definition: RNA_types.h:450
const char * description
Definition: RNA_types.h:452
IDPropertyData data
Definition: DNA_ID.h:80
void * first
Definition: DNA_listBase.h:47
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
struct wmKeyMapDiffItem * next
struct wmKeyMapDiffItem * prev
bool(* filter_fn)(const wmKeyMap *km, const wmKeyMapItem *kmi, void *user_data)
Definition: wm_keymap.c:62
struct PointerRNA * ptr
struct wmKeyMapItem * next
struct wmKeyMapItem * prev
bool(* poll_modal_item)(const struct wmOperator *op, int value)
bool(* poll)(struct bContext *)
const void * modal_items
struct wmKeyMap * modalkeymap
Definition: WM_types.h:820
struct StructRNA * srna
Definition: WM_types.h:802
PropertyRNA * prop
Definition: WM_types.h:814
struct wmKeyConfig * defaultconf
struct wmKeyConfig * userconf
struct wmKeyConfig * addonconf
#define G(x, y, z)
int WM_userdef_event_map(int kmitype)
bool WM_event_type_mask_test(const int event_type, const enum eEventType_Mask mask)
wmKeyMap * WM_event_get_keymap_from_handler(wmWindowManager *wm, wmEventHandler_Keymap *handler)
@ WM_HANDLER_TYPE_KEYMAP
#define ISTWEAK(event_type)
@ EVT_RIGHTCTRLKEY
@ EVT_TABKEY
@ EVT_DOWNARROWKEY
@ EVT_OSKEY
@ EVT_LEFTCTRLKEY
@ TABLET_ERASER
@ EVT_RIGHTARROWKEY
@ EVT_SPACEKEY
@ TABLET_STYLUS
@ EVT_RIGHTALTKEY
@ EVT_UPARROWKEY
@ EVT_LEFTARROWKEY
@ EVT_LEFTALTKEY
@ EVT_ESCKEY
@ EVT_BACKSPACEKEY
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
@ EVT_RETKEY
#define ISTIMER(event_type)
#define IS_EVENT_ACTIONZONE(event_type)
#define ISKEYBOARD(event_type)
#define EVT_TYPE_MASK_ALL
#define ISNDOF(event_type)
#define ISMOUSE(event_type)
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_keyconfig_clear(wmKeyConfig *keyconf)
Definition: wm_keymap.c:331
static char wm_keymap_update_flag
Definition: wm_keymap.c:1737
static wmKeyMapItem * wm_keymap_item_find_in_keymap(wmKeyMap *keymap, const char *opname, IDProperty *properties, const bool is_strict, const struct wmKeyMapItemFind_Params *params)
Definition: wm_keymap.c:1299
static void wm_user_modal_keymap_set_items(wmWindowManager *wm, wmKeyMap *km)
Definition: wm_keymap.c:997
static void keymap_item_set_id(wmKeyMap *keymap, wmKeyMapItem *kmi)
Definition: wm_keymap.c:494
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
Definition: wm_keymap.c:914
static wmKeyConfig * WM_keyconfig_active(wmWindowManager *wm)
Definition: wm_keymap.c:346
const char * WM_key_event_string(const short type, const bool compact)
Definition: wm_keymap.c:1046
int WM_modalkeymap_operator_items_to_string(wmOperatorType *ot, const int propvalue, const bool compact, char *result, const int result_len)
Definition: wm_keymap.c:1259
static wmKeyMapDiffItem * wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi)
Definition: wm_keymap.c:241
static wmKeyMapItem * wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle)
Definition: wm_keymap.c:583
wmKeyMapItem * WM_keymap_item_find_id(wmKeyMap *keymap, int id)
Definition: wm_keymap.c:1992
void WM_keymap_item_restore_to_default(wmWindowManager *wm, wmKeyMap *keymap, wmKeyMapItem *kmi)
Definition: wm_keymap.c:1920
static void wm_keymap_item_properties_update_ot_from_list(ListBase *km_lb)
Definition: wm_keymap.c:157
void WM_keymap_restore_to_default(wmKeyMap *keymap, wmWindowManager *wm)
Definition: wm_keymap.c:1977
static void wm_keymap_item_properties_set(wmKeyMapItem *kmi)
Definition: wm_keymap.c:108
wmKeyMapItem * WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value)
Definition: wm_keymap.c:927
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:852
wmKeyMap * WM_keymap_find_all(wmWindowManager *wm, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:866
void WM_keyconfig_update(wmWindowManager *wm)
Definition: wm_keymap.c:1781
@ WM_KEYMAP_UPDATE_RECONFIGURE
Definition: wm_keymap.c:1731
@ WM_KEYMAP_UPDATE_OPERATORTYPE
Definition: wm_keymap.c:1734
static wmKeyMapItem * wm_keymap_item_copy(wmKeyMapItem *kmi)
Definition: wm_keymap.c:72
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
Definition: wm_keymap.c:985
void WM_keymap_clear(wmKeyMap *keymap)
Definition: wm_keymap.c:424
static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap)
Definition: wm_keymap.c:563
static wmKeyMapItem * wm_keymap_item_find(const bContext *C, const char *opname, int opcontext, IDProperty *properties, bool is_strict, const struct wmKeyMapItemFind_Params *params, wmKeyMap **r_keymap)
Definition: wm_keymap.c:1488
wmKeyMapItem * WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
Definition: wm_keymap.c:506
int WM_modalkeymap_items_to_string(const wmKeyMap *km, const int propvalue, const bool compact, char *result, const int result_len)
Definition: wm_keymap.c:1230
wmKeyMapItem * WM_key_event_operator_from_keymap(wmKeyMap *keymap, const char *opname, IDProperty *properties, const short include_mask, const short exclude_mask)
Definition: wm_keymap.c:1650
const char * WM_bool_as_string(bool test)
Definition: wm_keymap.c:2003
wmKeyMap * WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:823
int WM_keymap_item_to_string(const wmKeyMapItem *kmi, const bool compact, char *result, const int result_len)
Definition: wm_keymap.c:1213
static wmKeyMap * wm_keymap_new(const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:384
static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
Definition: wm_keymap.c:639
wmKeyMapItem * WM_modalkeymap_add_item_str(wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value)
Definition: wm_keymap.c:944
static wmKeyMapItem * wm_keymap_item_find_props(const bContext *C, const char *opname, int opcontext, IDProperty *properties, const bool is_strict, const struct wmKeyMapItemFind_Params *params, wmKeyMap **r_keymap)
Definition: wm_keymap.c:1416
bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
Definition: wm_keymap.c:537
wmKeyMap * WM_keymap_active(const wmWindowManager *wm, wmKeyMap *keymap)
Definition: wm_keymap.c:1895
static bool wm_keymap_test_and_clear_update(wmKeyMap *km)
Definition: wm_keymap.c:1757
static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier)
Definition: wm_keymap.c:473
void WM_keyconfig_update_operatortype(void)
Definition: wm_keymap.c:1752
int WM_keymap_item_map_type_get(const wmKeyMapItem *kmi)
Definition: wm_keymap.c:207
wmKeyMap * WM_keymap_find_all_spaceid_or_empty(wmWindowManager *wm, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:871
static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi)
Definition: wm_keymap.c:256
void WM_keyconfig_free(wmKeyConfig *keyconf)
Definition: wm_keymap.c:340
bool WM_keymap_poll(bContext *C, wmKeyMap *keymap)
Definition: wm_keymap.c:451
static const char * key_event_glyph_or_text(const int font_id, const char *text, const char *single_glyph)
Definition: wm_keymap.c:1036
bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
Definition: wm_keymap.c:314
bool WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
Definition: wm_keymap.c:438
static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km)
Definition: wm_keymap.c:768
static wmKeyMapItem * wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int UNUSED(opcontext), IDProperty *properties, const bool is_strict, const struct wmKeyMapItemFind_Params *params, wmKeyMap **r_keymap)
Definition: wm_keymap.c:1381
wmKeyConfig * WM_keyconfig_new(wmWindowManager *wm, const char *idname, bool user_defined)
Definition: wm_keymap.c:278
static void wm_keymap_item_properties_update_ot(wmKeyMapItem *kmi)
Definition: wm_keymap.c:121
static bool kmi_filter_is_visible_type_mask(const wmKeyMap *km, const wmKeyMapItem *kmi, void *user_data)
Definition: wm_keymap.c:1613
static wmKeyMap * wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km)
Definition: wm_keymap.c:1770
static wmKeyMap * wm_keymap_copy(wmKeyMap *keymap)
Definition: wm_keymap.c:401
void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
Definition: wm_keymap.c:360
static wmKeyMapItem * wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle)
Definition: wm_keymap.c:572
const wmKeyMapItem * WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int propvalue)
Definition: wm_keymap.c:980
static const wmKeyMapItem * wm_modalkeymap_find_propvalue_iter(const wmKeyMap *km, const wmKeyMapItem *kmi, const int propvalue)
Definition: wm_keymap.c:961
static void wm_keymap_diff(wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km)
Definition: wm_keymap.c:594
static void wm_keymap_item_free(wmKeyMapItem *kmi)
Definition: wm_keymap.c:97
static wmKeyMap * wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap)
Definition: wm_keymap.c:702
static bool wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
Definition: wm_keymap.c:183
static bool kmi_filter_is_visible(const wmKeyMap *UNUSED(km), const wmKeyMapItem *kmi, void *UNUSED(user_data))
Definition: wm_keymap.c:1579
void WM_keyconfig_update_tag(wmKeyMap *keymap, wmKeyMapItem *kmi)
Definition: wm_keymap.c:1739
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition: wm_keymap.c:888
bool WM_keymap_item_compare(const wmKeyMapItem *k1, const wmKeyMapItem *k2)
Definition: wm_keymap.c:1669
char * WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, IDProperty *properties, const bool is_strict, char *result, const int result_len)
Definition: wm_keymap.c:1587
void WM_keymap_item_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties)
Definition: wm_keymap.c:193
wmKeyMapItem * WM_key_event_operator(const bContext *C, const char *opname, int opcontext, IDProperty *properties, const short include_mask, const short exclude_mask, wmKeyMap **r_keymap)
Definition: wm_keymap.c:1627
wmKeyMap * WM_keymap_list_find_spaceid_or_empty(ListBase *lb, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:836
char * WM_modalkeymap_operator_items_to_string_buf(wmOperatorType *ot, const int propvalue, const bool compact, const int max_len, int *r_available_len, char **r_result)
Definition: wm_keymap.c:1270
int WM_keymap_item_raw_to_string(const short shift, const short ctrl, const short alt, const short oskey, const short keymodifier, const short val, const short type, const bool compact, char *result, const int result_len)
Definition: wm_keymap.c:1142
static bool wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
Definition: wm_keymap.c:175
wmKeyMapItem * WM_keymap_add_item_copy(struct wmKeyMap *keymap, wmKeyMapItem *kmi_src)
Definition: wm_keymap.c:524
#define ADD_SEP
wmKeyConfig * WM_keyconfig_new_user(wmWindowManager *wm, const char *idname)
Definition: wm_keymap.c:309
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring)
Definition: wm_operators.c:605
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:584
bool WM_operator_properties_default(PointerRNA *ptr, const bool do_update)
Definition: wm_operators.c:657
void WM_operator_properties_create(PointerRNA *ptr, const char *opstring)
Definition: wm_operators.c:590
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:711
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
Definition: wm_operators.c:620