>From f2b6ebd4401ce9258a644a29060449b0579a59e9 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Wed, 28 Jan 2015 11:53:54 +0100 Subject: [PATCH] Let input queue deal gracefully with up-events * 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'. This patch makes Emacs deal consistently with such events. --- src/ChangeLog | 9 +++++++++ src/keyboard.c | 34 +++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d3f667e..d83f1e5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2015-01-28 David Kastrup + + * 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. + 2015-02-01 Martin Rudalics * xdisp.c (Fwindow_text_pixel_size): Add optional argument BUFFER. diff --git a/src/keyboard.c b/src/keyboard.c index 1176d70..ff200d4 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6215,6 +6215,10 @@ parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end) case 't': MULTI_LETTER_MOD (triple_modifier, "triple", 6); break; + + case 'u': + MULTI_LETTER_MOD (up_modifier, "up", 2); + break; #undef MULTI_LETTER_MOD } @@ -6262,16 +6266,18 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_ /* Since BASE could contain nulls, we can't use intern here; we have to use Fintern, which expects a genuine Lisp_String, and keeps a reference to it. */ - char new_mods[sizeof "A-C-H-M-S-s-down-drag-double-triple-"]; + char new_mods[sizeof "A-C-H-M-S-s-up-down-drag-double-triple-"]; int mod_len; { char *p = new_mods; - /* Only the event queue may use the `up' modifier; it should always - be turned into a click or drag event before presented to lisp code. */ - if (modifiers & up_modifier) - emacs_abort (); + /* Mouse events should not exhibit the `up' modifier; it should + always be turned into a click or drag event before being + presented to lisp code. And there should not be more than one + of up/down/click/drag anyway. But since Lisp events can be + synthesized, we don't take exception to unexpected + combinations */ if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; } if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } @@ -6281,6 +6287,7 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_ if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; } if (modifiers & double_modifier) p = stpcpy (p, "double-"); if (modifiers & triple_modifier) p = stpcpy (p, "triple-"); + if (modifiers & up_modifier) p = stpcpy (p, "up-"); if (modifiers & down_modifier) p = stpcpy (p, "down-"); if (modifiers & drag_modifier) p = stpcpy (p, "drag-"); /* The click modifier is denoted by the absence of other modifiers. */ @@ -6400,8 +6407,7 @@ DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers, BASE must be unmodified. This is like apply_modifiers_uncached, but uses BASE's - Qmodifier_cache property, if present. It also builds - Qevent_symbol_elements properties, since it has that info anyway. + Qmodifier_cache property, if present. apply_modifiers copies the value of BASE's Qevent_kind property to the modified symbol. */ @@ -6747,6 +6753,10 @@ parse_solitary_modifier (Lisp_Object symbol) MULTI_LETTER_MOD (triple_modifier, "triple", 6); break; + case 'u': + MULTI_LETTER_MOD (up_modifier, "up", 2); + break; + #undef SINGLE_LETTER_MOD #undef MULTI_LETTER_MOD } @@ -9454,14 +9464,16 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Drags reduce to clicks. Double-clicks reduce to clicks. Triple-clicks reduce to double-clicks, then to clicks. - Down-clicks are eliminated. + Up/Down-clicks are eliminated. Double-downs reduce to downs, then are eliminated. Triple-downs reduce to double-downs, then to downs, then are eliminated. */ - if (modifiers & (down_modifier | drag_modifier + if (modifiers & (up_modifier | down_modifier + | drag_modifier | double_modifier | triple_modifier)) { - while (modifiers & (down_modifier | drag_modifier + while (modifiers & (up_modifier | down_modifier + | drag_modifier | double_modifier | triple_modifier)) { Lisp_Object new_head, new_click; @@ -9473,7 +9485,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, modifiers &= ~drag_modifier; else { - /* Dispose of this `down' event by simply jumping + /* Dispose of this `up/down' event by simply jumping back to replay_key, to get another event. Note that if this event came from mock input, -- 2.1.0