aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Kastrup2015-01-28 11:53:54 +0100
committerDavid Kastrup2015-08-12 19:21:29 +0200
commitad0b6dd05a1a782dc12e921fc077aef46698e063 (patch)
treeaaf012106f40201fdfe031324c10021fe6c43897 /src
parentb367d7fc7b234bb98b330ac61bf35372f0f0acae (diff)
downloademacs-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.c35
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,