Subject: bug#29104: [PATCH]: xterm-mouse-mode clicks in the modeline dont use the keymap properties of the modeline strings

From: Olaf Rogalsky <[email-masked]>
Date: Tue, 07 Nov 2017 00:47:28 +0100

Hi,

I would like to give some more details on the patch and which problem it
tries to solve.

Ultimately I try to get better support of the mouse under xterm. The
following features currently do not work with the mouse under xterm:

1. Mouse clicks on menu-bar always brings up the left-most menu, but not
   the menu under the spot.
   
2. A mouse click on the mode-line activates the window, but does not
   trigger the local-map property on the spot.

3. When moving the mouse over some text with a mouse-face property or
   help-echo property nothing happens, because xterm-mouse-mode does not
   receive any mouse motion events from the controlling xterm (except
   during dragging operations).

I haven't looked into (1), but I am testing a solution for (2) and (3).

This patch (#29104) addresses (2). It does not implement a new feature,
but tries to make a bugfix to keyboard.c:read_key_sequence. This
function is a 900 lines nightmare of spaggheti code, full of global
state and goto's. At least it is somehow documented.

But here we go, this is what I understood so far:

The function reads input characters until some keybinding is found or
until the sequence does not form a prefix key sequence anymore. If the
trailing characters, which have been read so far, form a sequence in a
translation keymap (input-decode-map, key-translation-map,
local-function-key-map), those trailing characters are replaced by the
binding of the translation map.  Thereafter a jump back close to the
beginning of the function is made and all events up to the replacement
event are reinterpreted again.

Such jumps ("goto replay_sequence;") take place immediately after the
lines, which I introduced in the patch.  When replaying the sequence,
the variable "first_event" will be used to select the currently active
keymaps (line 9035).  In case, that the first characters are bound in a
key translation map, first_event still holds (incrorrectly, as I
presume) the first character of the translation sequence and not its
binding.

My patch takes place after a key translation has been performed.  It
checks, that the key translation is not empty, (or more precisely, that
the current event sequence is not empty),

           first_event = mock_input > 0 ? keybuf[0] : Qnil;  
                         ^^^^^^^^^^^^^^

and if so, sets the variable first_event to the first event in the
sequence.

           first_event = mock_input > 0 ? keybuf[0] : Qnil;  
                                          ^^^^^^^^^

Here, all key translations where allready replaced by their
corresponding binding.  If the current event sequence is empty,
first_event is set to Qnil, which means that the default active keymaps
should be used. This would be the case, if the raw key sequence was
bound to an empty vector in a translation map.

           first_event = mock_input > 0 ? keybuf[0] : Qnil;  
                                                      ^^^^

Now back to my original problem: mouse clicks in the mode line do not
work correctly. xterm-mouse-mode uses the input-decode-map to translate
special character sequences coming from xterm (starting with "\e[") into
proper mouse events.  Without the patch, first_event is set to ?\e.
Therefore the esc-map is used to find a binding for the mouse event,
which of cause does not work as intended. With the patch, first_event is
set to the mouse event and the binding in the local-map property will be
found.

Et vola, mouse clicks in the mode line will work :-)

Olaf

PS: You might ask, why I check for empty key translations.  I need those
    for (3).

-- 
Olaf Rogalsky
Schwörhausgasse 5
89073 Ulm
Germany