Subject: bug#19746: closed ()

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 14 Aug 2015 15:04:02 +0000

Your bug report

#19746: 25.0.50; Emacs should treat synthetic up-events gracefully

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
19746: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19746
GNU Bug Tracking System
Contact [email-masked] with problems

From: David Kastrup <[email-masked]>
To: [email-masked]
Date: Fri, 14 Aug 2015 17:03:23 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

-- 
David Kastrup

Subject: 25.0.50; Emacs should treat synthetic up-events gracefully
From: David Kastrup <[email-masked]>
To: [email-masked]
Date: Mon, 02 Feb 2015 20:15:12 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Emacs' mouse event code deals with the up- modifier (bit 0 in the
modifier mask) by converting it to click- or drag-events.  This happens
at the C level.

However, when synthesizing events for things like Midi keyboards
(basically computerized music instruments), it makes sense _not_ to
convert an up-key event to either a drag or click event since usually
the down-event is a principal event of its own: basically the
"importance relation" of down- and up-events is reversed for those kinds
of keys as compared to mouse buttons and this reflects in what kind of
event one would want representing it.

This patch allows the keymap machinery to treat the up- modifier in a
manner analog to the down-modifier even though Emacs will not (yet)
natively generate up-events itself.  However, it will allow sensible
behavior for such events being pushed into unread-command-events.

It has been proposed on the Emacs developer list on
<URL:http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00987.html>
and had some comments amended at
<URL:http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00993.html>.
However, there was an additional request at
<URL:http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg01031.html>
to change one comment in read_key_sequence to actions not matching the
code in read_key_sequence but rather happening in make_lispy_event.

The explanation why this change would be inappropriate in
<URL:http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg01035.html>
was after an additional exchange "resolved" with an ad hominem attack in
<URL:http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg01065.html>.

Further private communication led to no results.  In order to at least
provide users in need of this functionality with a referenceable issue
report (and possibly get someone else to apply the patch), I am
submitting the patch against current master here.

>From f2b6ebd4401ce9258a644a29060449b0579a59e9 Mon Sep 17 00:00:00 2001
From: David Kastrup <[email-masked]>
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  <[email-masked]>
+
+	* 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  <[email-masked]>
 
 	* 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

In GNU Emacs 25.0.50.2 (i686-pc-linux-gnu, GTK+ Version 3.12.2)
 of 2014-12-19 on lola
Repository revision: c683666bcd0f0675ba72894a4a6374cf15849385
Windowing system distributor `The X.Org Foundation', version 11.0.11600000
System Description:	Ubuntu 14.10

Configured using:
 `configure --without-toolkit-scroll-bars'

Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GCONF GSETTINGS
NOTIFY LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB

Important settings:
  value of $LC_MONETARY: en_US.UTF-8
  value of $LC_NUMERIC: en_US.UTF-8
  value of $LC_TIME: en_US.UTF-8
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Fundamental

Minor modes in effect:
  shell-dirtrack-mode: t
  TeX-PDF-mode: t
  diff-auto-refine-mode: t
  desktop-save-mode: t
  minibuffer-electric-default-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t

Recent messages:
No more unread articles
Making completion list...
Found `patches, sending' in Concept Index.  (Only match)
Quit
Are you sure you want to quit reading news? (y or n) y
(No changes need to be saved)
Saving /home/dak/.newsrc.eld...
Saving file /home/dak/.newsrc.eld...
Wrote /home/dak/.newsrc.eld
Saving /home/dak/.newsrc.eld...done

Load-path shadows:
None found.

Features:
(shadow emacsbug sgml-mode nndoc tramp-cache tramp-sh tramp tramp-compat
tramp-loaddefs trampver shell pcomplete gnus-dup help-mode debug
thingatpt pp rfc2368 sendmail nnir flow-fill shr dom subr-x pcase
browse-url mm-archive mule-util sort smiley gnus-cite mail-extr
gnus-async gnus-bcklg gnus-kill qp gnus-ml disp-table pop3 nndir nndraft
nnmh gnutls network-stream nsm auth-source cl-macs gv eieio eieio-core
starttls nnml nnfolder nnnil gnus-agent gnus-srvr gnus-score score-mode
nnvirtual gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime
password-cache dig mailcap nntp gnus-cache gnus-sum gnus-group gnus-undo
gnus-start gnus-cloud nnimap nnmail mail-source tls utf7 netrc nnoo
parse-time gnus-spec gnus-int gnus-range message format-spec rfc822 mml
mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev gmm-utils mailheader gnus-win sh-script smie
executable make-mode smerge-mode scheme latexenc nxml-uchnm rng-xsd
xsd-regexp rng-cmpct rng-nxml rng-valid rng-loc rng-uri rng-parse
nxml-parse rng-match rng-dt rng-util rng-pttrn nxml-ns nxml-mode
nxml-outln nxml-rap nxml-util nxml-glyph nxml-enc xmltok dired-x dired
python json tex-info texinfo autorevert filenotify cc-mode cc-fonts
cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs
lilypond-mode compile comint ansi-color ring bug-reference add-log
preview prv-emacs reftex-dcr reftex-auc reftex reftex-vars tex-bar
tex-buf toolbar-x noutline outline font-latex byte-opt bytecomp
byte-compile cl-extra cconv latex edmacro kmacro tex-style tex dbus xml
crm vc-git diff-mode easy-mmode jka-compr info easymenu package
epg-config advice desktop frameset minibuf-eldef gnus gnus-ems nnheader
gnus-util mail-utils mm-util help-fns mail-prsvr wid-edit cl-loaddefs
cl-lib cus-start cus-load preview-latex tex-site auto-loads server
time-date tooltip eldoc electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel x-win x-dnd tool-bar dnd fontset image regexp-opt
fringe tabulated-list newcomment elisp-mode lisp-mode prog-mode register
page menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock
font-lock syntax facemenu font-core frame cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese hebrew
greek romanian slovak czech european ethiopic indian cyrillic chinese
case-table epa-hook jka-cmpr-hook help simple abbrev minibuffer nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process dbusbind
gfilenotify dynamic-setting system-font-setting font-render-setting
move-toolbar gtk x-toolkit x multi-tty emacs)

Memory information:
((conses 8 739868 45106)
 (symbols 24 52766 375)
 (miscs 20 1596 1711)
 (strings 16 120678 18300)
 (string-bytes 1 3817797)
 (vectors 8 47334)
 (vector-slots 4 1796732 49030)
 (floats 8 385 606)
 (intervals 28 63060 1020)
 (buffers 520 276)
 (heap 1024 63553 15724))

-- 
David Kastrup