[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Deal gracefully with up-events (Bug#19746)
From: |
David Kastrup |
Subject: |
[PATCH] Deal gracefully with up-events (Bug#19746) |
Date: |
Mon, 10 Aug 2015 15:59:16 +0200 |
* 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.
---
src/keyboard.c | 35 ++++++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 11 deletions(-)
diff --git a/src/keyboard.c b/src/keyboard.c
index e4fe5b9..78e2cf9 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6230,6 +6230,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
}
@@ -6277,16 +6281,19 @@ 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 once they
+ leave the event queue only accessible to C code; `up' will
+ always be turned into a click or drag event before being
+ presented to lisp code. But since lisp events can be
+ synthesized bypassing the event queue and pushed into
+ `unread-command-events' or its companions, it's better to just
+ deal with unexpected modifier combinations. */
if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; }
if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; }
@@ -6296,6 +6303,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. */
@@ -6415,8 +6423,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. */
@@ -6762,6 +6769,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
}
@@ -9475,14 +9486,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;
@@ -9494,7 +9507,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.4
- [no subject], David Kastrup, 2015/08/10
- [PATCH] Deal gracefully with up-events (Bug#19746),
David Kastrup <=
- Re: (unknown), David Kastrup, 2015/08/10