Subject: bug#76669: read_key_sequence discards events without attempting remapping

From: Eli Zaretskii <[email-masked]>
Date: Sun, 02 Mar 2025 07:51:35 +0200

> From: Daniel Colascione <[email-masked]>
> Date: Sat, 01 Mar 2025 18:35:31 -0500
> 
> Suppose we want to use local-function-key-map to translate
> s-<down-mouse-3> to <down-mouse-3>.  If we don't have a concrete binding
> for s-<down-mouse-3>, we never attempt to translate it: instead,
> read_key_sequence discards the down event and skips right to
> s-<mouse-3>, which we *can* translate.

I think it's ambiguous which one should come first: the discarding of
'down' modifier or translation via that map.  The ELisp manual says:

     The function ‘read-key-sequence’ ignores any button-down events that
  don't have command bindings; therefore, the Emacs command loop ignores
  them too.  This means that you need not worry about defining button-down
  events unless you want them to do something.  The usual reason to define
  a button-down event is so that you can track mouse motion (by reading
  motion events) until the button is released.  *Note Motion Events::.

And also:

     If an input character is upper-case (or has the shift modifier) and
  has no key binding, but its lower-case equivalent has one, then
  ‘read-key-sequence’ converts the character to lower case.  (This
  behavior can be disabled by setting the
  ‘translate-upper-case-key-bindings’ user option to ‘nil’.)  Note that
  ‘lookup-key’ does not perform case conversion in this way.

     When reading input results in such a “shift-translation”, Emacs sets
  the variable ‘this-command-keys-shift-translated’ to a non-‘nil’ value.
  Lisp programs can examine this variable if they need to modify their
  behavior when invoked by shift-translated keys.  For example, the
  function ‘handle-shift-selection’ examines the value of this variable to
  determine how to activate or deactivate the region (*note
  handle-shift-selection: The Mark.).

     The function ‘read-key-sequence’ also transforms some mouse events.
  It converts unbound drag events into click events, and discards unbound
  button-down events entirely.  It also reshuffles focus events and
  miscellaneous window events so that they never appear in a key sequence
  with any other events.

Adding Stefan to the discussion.