diff options
| author | David Kastrup | 2015-01-28 11:53:54 +0100 |
|---|---|---|
| committer | David Kastrup | 2015-08-12 19:21:29 +0200 |
| commit | ad0b6dd05a1a782dc12e921fc077aef46698e063 (patch) | |
| tree | aaf012106f40201fdfe031324c10021fe6c43897 /src | |
| parent | b367d7fc7b234bb98b330ac61bf35372f0f0acae (diff) | |
| download | emacs-ad0b6dd05a1a782dc12e921fc077aef46698e063.tar.gz emacs-ad0b6dd05a1a782dc12e921fc077aef46698e063.zip | |
Deal gracefully with up-events (Bug#19746)
* keyboard.c (apply_modifiers_uncached, parse_solitary_modifier)
(parse_modifiers_uncached): React gracefully to "up-" modifiers:
those may easily be injected by user-level Lisp code.
(read_key_sequence): Discard unbound up-events like unbound
down-events: they are even more likely only relevant for special
purposes.
While Emacs will not produce up-events on its own currently (those are
converted to drag or click events before being converted to
Lisp-readable structures), the input queue can be made to contain them
by synthesizing events to `unread-command-events'. Emacs should deal
consistently with such events.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index f670da3db5e..6f626b79920 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -6241,6 +6241,10 @@ parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end) | |||
| 6241 | case 't': | 6241 | case 't': |
| 6242 | MULTI_LETTER_MOD (triple_modifier, "triple", 6); | 6242 | MULTI_LETTER_MOD (triple_modifier, "triple", 6); |
| 6243 | break; | 6243 | break; |
| 6244 | |||
| 6245 | case 'u': | ||
| 6246 | MULTI_LETTER_MOD (up_modifier, "up", 2); | ||
| 6247 | break; | ||
| 6244 | #undef MULTI_LETTER_MOD | 6248 | #undef MULTI_LETTER_MOD |
| 6245 | 6249 | ||
| 6246 | } | 6250 | } |
| @@ -6288,16 +6292,19 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_ | |||
| 6288 | /* Since BASE could contain nulls, we can't use intern here; we have | 6292 | /* Since BASE could contain nulls, we can't use intern here; we have |
| 6289 | to use Fintern, which expects a genuine Lisp_String, and keeps a | 6293 | to use Fintern, which expects a genuine Lisp_String, and keeps a |
| 6290 | reference to it. */ | 6294 | reference to it. */ |
| 6291 | char new_mods[sizeof "A-C-H-M-S-s-down-drag-double-triple-"]; | 6295 | char new_mods[sizeof "A-C-H-M-S-s-up-down-drag-double-triple-"]; |
| 6292 | int mod_len; | 6296 | int mod_len; |
| 6293 | 6297 | ||
| 6294 | { | 6298 | { |
| 6295 | char *p = new_mods; | 6299 | char *p = new_mods; |
| 6296 | 6300 | ||
| 6297 | /* Only the event queue may use the `up' modifier; it should always | 6301 | /* Mouse events should not exhibit the `up' modifier once they |
| 6298 | be turned into a click or drag event before presented to lisp code. */ | 6302 | leave the event queue only accessible to C code; `up' will |
| 6299 | if (modifiers & up_modifier) | 6303 | always be turned into a click or drag event before being |
| 6300 | emacs_abort (); | 6304 | presented to lisp code. But since lisp events can be |
| 6305 | synthesized bypassing the event queue and pushed into | ||
| 6306 | `unread-command-events' or its companions, it's better to just | ||
| 6307 | deal with unexpected modifier combinations. */ | ||
| 6301 | 6308 | ||
| 6302 | if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; } | 6309 | if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; } |
| 6303 | if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } | 6310 | if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } |
| @@ -6307,6 +6314,7 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_ | |||
| 6307 | if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; } | 6314 | if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; } |
| 6308 | if (modifiers & double_modifier) p = stpcpy (p, "double-"); | 6315 | if (modifiers & double_modifier) p = stpcpy (p, "double-"); |
| 6309 | if (modifiers & triple_modifier) p = stpcpy (p, "triple-"); | 6316 | if (modifiers & triple_modifier) p = stpcpy (p, "triple-"); |
| 6317 | if (modifiers & up_modifier) p = stpcpy (p, "up-"); | ||
| 6310 | if (modifiers & down_modifier) p = stpcpy (p, "down-"); | 6318 | if (modifiers & down_modifier) p = stpcpy (p, "down-"); |
| 6311 | if (modifiers & drag_modifier) p = stpcpy (p, "drag-"); | 6319 | if (modifiers & drag_modifier) p = stpcpy (p, "drag-"); |
| 6312 | /* The click modifier is denoted by the absence of other modifiers. */ | 6320 | /* The click modifier is denoted by the absence of other modifiers. */ |
| @@ -6426,8 +6434,7 @@ DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers, | |||
| 6426 | BASE must be unmodified. | 6434 | BASE must be unmodified. |
| 6427 | 6435 | ||
| 6428 | This is like apply_modifiers_uncached, but uses BASE's | 6436 | This is like apply_modifiers_uncached, but uses BASE's |
| 6429 | Qmodifier_cache property, if present. It also builds | 6437 | Qmodifier_cache property, if present. |
| 6430 | Qevent_symbol_elements properties, since it has that info anyway. | ||
| 6431 | 6438 | ||
| 6432 | apply_modifiers copies the value of BASE's Qevent_kind property to | 6439 | apply_modifiers copies the value of BASE's Qevent_kind property to |
| 6433 | the modified symbol. */ | 6440 | the modified symbol. */ |
| @@ -6773,6 +6780,10 @@ parse_solitary_modifier (Lisp_Object symbol) | |||
| 6773 | MULTI_LETTER_MOD (triple_modifier, "triple", 6); | 6780 | MULTI_LETTER_MOD (triple_modifier, "triple", 6); |
| 6774 | break; | 6781 | break; |
| 6775 | 6782 | ||
| 6783 | case 'u': | ||
| 6784 | MULTI_LETTER_MOD (up_modifier, "up", 2); | ||
| 6785 | break; | ||
| 6786 | |||
| 6776 | #undef SINGLE_LETTER_MOD | 6787 | #undef SINGLE_LETTER_MOD |
| 6777 | #undef MULTI_LETTER_MOD | 6788 | #undef MULTI_LETTER_MOD |
| 6778 | } | 6789 | } |
| @@ -9486,14 +9497,16 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9486 | Drags reduce to clicks. | 9497 | Drags reduce to clicks. |
| 9487 | Double-clicks reduce to clicks. | 9498 | Double-clicks reduce to clicks. |
| 9488 | Triple-clicks reduce to double-clicks, then to clicks. | 9499 | Triple-clicks reduce to double-clicks, then to clicks. |
| 9489 | Down-clicks are eliminated. | 9500 | Up/Down-clicks are eliminated. |
| 9490 | Double-downs reduce to downs, then are eliminated. | 9501 | Double-downs reduce to downs, then are eliminated. |
| 9491 | Triple-downs reduce to double-downs, then to downs, | 9502 | Triple-downs reduce to double-downs, then to downs, |
| 9492 | then are eliminated. */ | 9503 | then are eliminated. */ |
| 9493 | if (modifiers & (down_modifier | drag_modifier | 9504 | if (modifiers & (up_modifier | down_modifier |
| 9505 | | drag_modifier | ||
| 9494 | | double_modifier | triple_modifier)) | 9506 | | double_modifier | triple_modifier)) |
| 9495 | { | 9507 | { |
| 9496 | while (modifiers & (down_modifier | drag_modifier | 9508 | while (modifiers & (up_modifier | down_modifier |
| 9509 | | drag_modifier | ||
| 9497 | | double_modifier | triple_modifier)) | 9510 | | double_modifier | triple_modifier)) |
| 9498 | { | 9511 | { |
| 9499 | Lisp_Object new_head, new_click; | 9512 | Lisp_Object new_head, new_click; |
| @@ -9505,7 +9518,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9505 | modifiers &= ~drag_modifier; | 9518 | modifiers &= ~drag_modifier; |
| 9506 | else | 9519 | else |
| 9507 | { | 9520 | { |
| 9508 | /* Dispose of this `down' event by simply jumping | 9521 | /* Dispose of this `up/down' event by simply jumping |
| 9509 | back to replay_key, to get another event. | 9522 | back to replay_key, to get another event. |
| 9510 | 9523 | ||
| 9511 | Note that if this event came from mock input, | 9524 | Note that if this event came from mock input, |