diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 501174faaca..754a80fe74b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -452,6 +452,10 @@ int input_pending; | |||
| 452 | 452 | ||
| 453 | int meta_key; | 453 | int meta_key; |
| 454 | 454 | ||
| 455 | /* Non-zero means force key bindings update in parse_menu_item. */ | ||
| 456 | |||
| 457 | int update_menu_bindings; | ||
| 458 | |||
| 455 | extern char *pending_malloc_warning; | 459 | extern char *pending_malloc_warning; |
| 456 | 460 | ||
| 457 | /* Circular buffer for pre-read keyboard input. */ | 461 | /* Circular buffer for pre-read keyboard input. */ |
| @@ -6482,11 +6486,11 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6482 | 6486 | ||
| 6483 | /* Initialize optional entries. */ | 6487 | /* Initialize optional entries. */ |
| 6484 | for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++) | 6488 | for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++) |
| 6485 | XVECTOR (item_properties)->contents[i] = Qnil; | 6489 | AREF (item_properties, i) = Qnil; |
| 6486 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = Qt; | 6490 | AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt; |
| 6487 | 6491 | ||
| 6488 | /* Save the item here to protect it from GC. */ | 6492 | /* Save the item here to protect it from GC. */ |
| 6489 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_ITEM] = item; | 6493 | AREF (item_properties, ITEM_PROPERTY_ITEM) = item; |
| 6490 | 6494 | ||
| 6491 | item_string = XCAR (item); | 6495 | item_string = XCAR (item); |
| 6492 | 6496 | ||
| @@ -6495,13 +6499,12 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6495 | if (STRINGP (item_string)) | 6499 | if (STRINGP (item_string)) |
| 6496 | { | 6500 | { |
| 6497 | /* Old format menu item. */ | 6501 | /* Old format menu item. */ |
| 6498 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string; | 6502 | AREF (item_properties, ITEM_PROPERTY_NAME) = item_string; |
| 6499 | 6503 | ||
| 6500 | /* Maybe help string. */ | 6504 | /* Maybe help string. */ |
| 6501 | if (CONSP (item) && STRINGP (XCAR (item))) | 6505 | if (CONSP (item) && STRINGP (XCAR (item))) |
| 6502 | { | 6506 | { |
| 6503 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] | 6507 | AREF (item_properties, ITEM_PROPERTY_HELP) = XCAR (item); |
| 6504 | = XCAR (item); | ||
| 6505 | start = item; | 6508 | start = item; |
| 6506 | item = XCDR (item); | 6509 | item = XCDR (item); |
| 6507 | } | 6510 | } |
| @@ -6516,27 +6519,25 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6516 | } | 6519 | } |
| 6517 | 6520 | ||
| 6518 | /* This is the real definition--the function to run. */ | 6521 | /* This is the real definition--the function to run. */ |
| 6519 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = item; | 6522 | AREF (item_properties, ITEM_PROPERTY_DEF) = item; |
| 6520 | 6523 | ||
| 6521 | /* Get enable property, if any. */ | 6524 | /* Get enable property, if any. */ |
| 6522 | if (SYMBOLP (item)) | 6525 | if (SYMBOLP (item)) |
| 6523 | { | 6526 | { |
| 6524 | tem = Fget (item, Qmenu_enable); | 6527 | tem = Fget (item, Qmenu_enable); |
| 6525 | if (!NILP (tem)) | 6528 | if (!NILP (tem)) |
| 6526 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem; | 6529 | AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem; |
| 6527 | } | 6530 | } |
| 6528 | } | 6531 | } |
| 6529 | else if (EQ (item_string, Qmenu_item) && CONSP (item)) | 6532 | else if (EQ (item_string, Qmenu_item) && CONSP (item)) |
| 6530 | { | 6533 | { |
| 6531 | /* New format menu item. */ | 6534 | /* New format menu item. */ |
| 6532 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] | 6535 | AREF (item_properties, ITEM_PROPERTY_NAME) = XCAR (item); |
| 6533 | = XCAR (item); | ||
| 6534 | start = XCDR (item); | 6536 | start = XCDR (item); |
| 6535 | if (CONSP (start)) | 6537 | if (CONSP (start)) |
| 6536 | { | 6538 | { |
| 6537 | /* We have a real binding. */ | 6539 | /* We have a real binding. */ |
| 6538 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] | 6540 | AREF (item_properties, ITEM_PROPERTY_DEF) = XCAR (start); |
| 6539 | = XCAR (start); | ||
| 6540 | 6541 | ||
| 6541 | item = XCDR (start); | 6542 | item = XCDR (start); |
| 6542 | /* Is there a cache list with key equivalences. */ | 6543 | /* Is there a cache list with key equivalences. */ |
| @@ -6553,8 +6554,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6553 | item = XCDR (item); | 6554 | item = XCDR (item); |
| 6554 | 6555 | ||
| 6555 | if (EQ (tem, QCenable)) | 6556 | if (EQ (tem, QCenable)) |
| 6556 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] | 6557 | AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item); |
| 6557 | = XCAR (item); | ||
| 6558 | else if (EQ (tem, QCvisible) && !notreal) | 6558 | else if (EQ (tem, QCvisible) && !notreal) |
| 6559 | { | 6559 | { |
| 6560 | /* If got a visible property and that evaluates to nil | 6560 | /* If got a visible property and that evaluates to nil |
| @@ -6564,8 +6564,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6564 | return 0; | 6564 | return 0; |
| 6565 | } | 6565 | } |
| 6566 | else if (EQ (tem, QChelp)) | 6566 | else if (EQ (tem, QChelp)) |
| 6567 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] | 6567 | AREF (item_properties, ITEM_PROPERTY_HELP) = XCAR (item); |
| 6568 | = XCAR (item); | ||
| 6569 | else if (EQ (tem, QCfilter)) | 6568 | else if (EQ (tem, QCfilter)) |
| 6570 | filter = item; | 6569 | filter = item; |
| 6571 | else if (EQ (tem, QCkey_sequence)) | 6570 | else if (EQ (tem, QCkey_sequence)) |
| @@ -6580,8 +6579,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6580 | { | 6579 | { |
| 6581 | tem = XCAR (item); | 6580 | tem = XCAR (item); |
| 6582 | if (CONSP (tem) || (STRINGP (tem) && NILP (cachelist))) | 6581 | if (CONSP (tem) || (STRINGP (tem) && NILP (cachelist))) |
| 6583 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ] | 6582 | AREF (item_properties, ITEM_PROPERTY_KEYEQ) = tem; |
| 6584 | = tem; | ||
| 6585 | } | 6583 | } |
| 6586 | else if (EQ (tem, QCbutton) && CONSP (XCAR (item))) | 6584 | else if (EQ (tem, QCbutton) && CONSP (XCAR (item))) |
| 6587 | { | 6585 | { |
| @@ -6590,9 +6588,9 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6590 | type = XCAR (tem); | 6588 | type = XCAR (tem); |
| 6591 | if (EQ (type, QCtoggle) || EQ (type, QCradio)) | 6589 | if (EQ (type, QCtoggle) || EQ (type, QCradio)) |
| 6592 | { | 6590 | { |
| 6593 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED] | 6591 | AREF (item_properties, ITEM_PROPERTY_SELECTED) |
| 6594 | = XCDR (tem); | 6592 | = XCDR (tem); |
| 6595 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE] | 6593 | AREF (item_properties, ITEM_PROPERTY_TYPE) |
| 6596 | = type; | 6594 | = type; |
| 6597 | } | 6595 | } |
| 6598 | } | 6596 | } |
| @@ -6607,23 +6605,23 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6607 | 6605 | ||
| 6608 | /* If item string is not a string, evaluate it to get string. | 6606 | /* If item string is not a string, evaluate it to get string. |
| 6609 | If we don't get a string, skip this item. */ | 6607 | If we don't get a string, skip this item. */ |
| 6610 | item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]; | 6608 | item_string = AREF (item_properties, ITEM_PROPERTY_NAME); |
| 6611 | if (!(STRINGP (item_string) || notreal)) | 6609 | if (!(STRINGP (item_string) || notreal)) |
| 6612 | { | 6610 | { |
| 6613 | item_string = menu_item_eval_property (item_string); | 6611 | item_string = menu_item_eval_property (item_string); |
| 6614 | if (!STRINGP (item_string)) | 6612 | if (!STRINGP (item_string)) |
| 6615 | return 0; | 6613 | return 0; |
| 6616 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string; | 6614 | AREF (item_properties, ITEM_PROPERTY_NAME) = item_string; |
| 6617 | } | 6615 | } |
| 6618 | 6616 | ||
| 6619 | /* If got a filter apply it on definition. */ | 6617 | /* If got a filter apply it on definition. */ |
| 6620 | def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]; | 6618 | def = AREF (item_properties, ITEM_PROPERTY_DEF); |
| 6621 | if (!NILP (filter)) | 6619 | if (!NILP (filter)) |
| 6622 | { | 6620 | { |
| 6623 | def = menu_item_eval_property (list2 (XCAR (filter), | 6621 | def = menu_item_eval_property (list2 (XCAR (filter), |
| 6624 | list2 (Qquote, def))); | 6622 | list2 (Qquote, def))); |
| 6625 | 6623 | ||
| 6626 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = def; | 6624 | AREF (item_properties, ITEM_PROPERTY_DEF) = def; |
| 6627 | } | 6625 | } |
| 6628 | 6626 | ||
| 6629 | /* If we got no definition, this item is just unselectable text which | 6627 | /* If we got no definition, this item is just unselectable text which |
| @@ -6632,7 +6630,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6632 | return (inmenubar ? 0 : 1); | 6630 | return (inmenubar ? 0 : 1); |
| 6633 | 6631 | ||
| 6634 | /* Enable or disable selection of item. */ | 6632 | /* Enable or disable selection of item. */ |
| 6635 | tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]; | 6633 | tem = AREF (item_properties, ITEM_PROPERTY_ENABLE); |
| 6636 | if (!EQ (tem, Qt)) | 6634 | if (!EQ (tem, Qt)) |
| 6637 | { | 6635 | { |
| 6638 | if (notreal) | 6636 | if (notreal) |
| @@ -6641,19 +6639,20 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6641 | tem = menu_item_eval_property (tem); | 6639 | tem = menu_item_eval_property (tem); |
| 6642 | if (inmenubar && NILP (tem)) | 6640 | if (inmenubar && NILP (tem)) |
| 6643 | return 0; /* Ignore disabled items in menu bar. */ | 6641 | return 0; /* Ignore disabled items in menu bar. */ |
| 6644 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem; | 6642 | AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem; |
| 6645 | } | 6643 | } |
| 6646 | 6644 | ||
| 6647 | /* See if this is a separate pane or a submenu. */ | 6645 | /* See if this is a separate pane or a submenu. */ |
| 6648 | def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]; | 6646 | def = AREF (item_properties, ITEM_PROPERTY_DEF); |
| 6649 | tem = get_keymap_1 (def, 0, 1); | 6647 | tem = get_keymap_1 (def, 0, 1); |
| 6650 | /* For a subkeymap, just record its details and exit. */ | 6648 | /* For a subkeymap, just record its details and exit. */ |
| 6651 | if (!NILP (tem)) | 6649 | if (!NILP (tem)) |
| 6652 | { | 6650 | { |
| 6653 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP] = tem; | 6651 | AREF (item_properties, ITEM_PROPERTY_MAP) = tem; |
| 6654 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = tem; | 6652 | AREF (item_properties, ITEM_PROPERTY_DEF) = tem; |
| 6655 | return 1; | 6653 | return 1; |
| 6656 | } | 6654 | } |
| 6655 | |||
| 6657 | /* At the top level in the menu bar, do likewise for commands also. | 6656 | /* At the top level in the menu bar, do likewise for commands also. |
| 6658 | The menu bar does not display equivalent key bindings anyway. | 6657 | The menu bar does not display equivalent key bindings anyway. |
| 6659 | ITEM_PROPERTY_DEF is already set up properly. */ | 6658 | ITEM_PROPERTY_DEF is already set up properly. */ |
| @@ -6668,7 +6667,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6668 | XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start)); | 6667 | XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start)); |
| 6669 | cachelist = XCAR (XCDR (start)); | 6668 | cachelist = XCAR (XCDR (start)); |
| 6670 | newcache = 1; | 6669 | newcache = 1; |
| 6671 | tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]; | 6670 | tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ); |
| 6672 | if (!NILP (keyhint)) | 6671 | if (!NILP (keyhint)) |
| 6673 | { | 6672 | { |
| 6674 | XCAR (cachelist) = XCAR (keyhint); | 6673 | XCAR (cachelist) = XCAR (keyhint); |
| @@ -6680,6 +6679,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6680 | XCAR (cachelist) = Qt; | 6679 | XCAR (cachelist) = Qt; |
| 6681 | } | 6680 | } |
| 6682 | } | 6681 | } |
| 6682 | |||
| 6683 | tem = XCAR (cachelist); | 6683 | tem = XCAR (cachelist); |
| 6684 | if (!EQ (tem, Qt)) | 6684 | if (!EQ (tem, Qt)) |
| 6685 | { | 6685 | { |
| @@ -6689,21 +6689,22 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6689 | if (!NILP (tem)) | 6689 | if (!NILP (tem)) |
| 6690 | tem = Fkey_binding (tem, Qnil); | 6690 | tem = Fkey_binding (tem, Qnil); |
| 6691 | 6691 | ||
| 6692 | prefix = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]; | 6692 | prefix = AREF (item_properties, ITEM_PROPERTY_KEYEQ); |
| 6693 | if (CONSP (prefix)) | 6693 | if (CONSP (prefix)) |
| 6694 | { | 6694 | { |
| 6695 | def = XCAR (prefix); | 6695 | def = XCAR (prefix); |
| 6696 | prefix = XCDR (prefix); | 6696 | prefix = XCDR (prefix); |
| 6697 | } | 6697 | } |
| 6698 | else | 6698 | else |
| 6699 | def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]; | 6699 | def = AREF (item_properties, ITEM_PROPERTY_DEF); |
| 6700 | 6700 | ||
| 6701 | if (NILP (XCAR (cachelist))) /* Have no saved key. */ | 6701 | if (!update_menu_bindings) |
| 6702 | chkcache = 0; | ||
| 6703 | else if (NILP (XCAR (cachelist))) /* Have no saved key. */ | ||
| 6702 | { | 6704 | { |
| 6703 | if (newcache /* Always check first time. */ | 6705 | if (newcache /* Always check first time. */ |
| 6704 | /* Should we check everything when precomputing key | 6706 | /* Should we check everything when precomputing key |
| 6705 | bindings? */ | 6707 | bindings? */ |
| 6706 | /* || notreal */ | ||
| 6707 | /* If something had no key binding before, don't recheck it | 6708 | /* If something had no key binding before, don't recheck it |
| 6708 | because that is too slow--except if we have a list of | 6709 | because that is too slow--except if we have a list of |
| 6709 | rebound commands in Vdefine_key_rebound_commands, do | 6710 | rebound commands in Vdefine_key_rebound_commands, do |
| @@ -6728,7 +6729,8 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6728 | command name has equivalent keys. Otherwise look up the | 6729 | command name has equivalent keys. Otherwise look up the |
| 6729 | specified command itself. We don't try both, because that | 6730 | specified command itself. We don't try both, because that |
| 6730 | makes lmenu menus slow. */ | 6731 | makes lmenu menus slow. */ |
| 6731 | if (SYMBOLP (def) && SYMBOLP (XSYMBOL (def)->function) | 6732 | if (SYMBOLP (def) |
| 6733 | && SYMBOLP (XSYMBOL (def)->function) | ||
| 6732 | && ! NILP (Fget (def, Qmenu_alias))) | 6734 | && ! NILP (Fget (def, Qmenu_alias))) |
| 6733 | def = XSYMBOL (def)->function; | 6735 | def = XSYMBOL (def)->function; |
| 6734 | tem = Fwhere_is_internal (def, Qnil, Qt, Qnil); | 6736 | tem = Fwhere_is_internal (def, Qnil, Qt, Qnil); |
| @@ -6772,7 +6774,7 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6772 | return 1; | 6774 | return 1; |
| 6773 | 6775 | ||
| 6774 | /* If we have an equivalent key binding, use that. */ | 6776 | /* If we have an equivalent key binding, use that. */ |
| 6775 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ] = tem; | 6777 | AREF (item_properties, ITEM_PROPERTY_KEYEQ) = tem; |
| 6776 | 6778 | ||
| 6777 | /* Include this when menu help is implemented. | 6779 | /* Include this when menu help is implemented. |
| 6778 | tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]; | 6780 | tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]; |
| @@ -6786,9 +6788,9 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6786 | */ | 6788 | */ |
| 6787 | 6789 | ||
| 6788 | /* Handle radio buttons or toggle boxes. */ | 6790 | /* Handle radio buttons or toggle boxes. */ |
| 6789 | tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]; | 6791 | tem = AREF (item_properties, ITEM_PROPERTY_SELECTED); |
| 6790 | if (!NILP (tem)) | 6792 | if (!NILP (tem)) |
| 6791 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED] | 6793 | AREF (item_properties, ITEM_PROPERTY_SELECTED) |
| 6792 | = menu_item_eval_property (tem); | 6794 | = menu_item_eval_property (tem); |
| 6793 | 6795 | ||
| 6794 | return 1; | 6796 | return 1; |
| @@ -10628,6 +10630,12 @@ The default value is nil, in which case, point adjustment are\n\ | |||
| 10628 | suppressed only after special commands that set\n\ | 10630 | suppressed only after special commands that set\n\ |
| 10629 | `disable-point-adjustment' (which see) to non-nil."); | 10631 | `disable-point-adjustment' (which see) to non-nil."); |
| 10630 | Vglobal_disable_point_adjustment = Qnil; | 10632 | Vglobal_disable_point_adjustment = Qnil; |
| 10633 | |||
| 10634 | DEFVAR_LISP ("update-menu-bindings", &update_menu_bindings, | ||
| 10635 | "Non-nil means updating menu bindings is allowed.\n\ | ||
| 10636 | A value of nil means menu bindings should not be updated.\n\ | ||
| 10637 | Used during Emacs' startup."); | ||
| 10638 | update_menu_bindings = 1; | ||
| 10631 | } | 10639 | } |
| 10632 | 10640 | ||
| 10633 | void | 10641 | void |