How to restore Shift+MouseButton = select when mouse protocol is enabled in xterm 361

clipboardmousexterm

In xterm, in vim or other applications that can use the mouse in xterm, I used to be able to hold the Shift key to bypass that mouse button handling and do normal X selection.

With the latest update to xterm version 361 on Debian, that no longer works. In vim, Shift+LeftButton now seems to scroll down instead. After I enter printf '\e[?1000h', I see that Shift+LeftButton sends something like \e[M$xy instead.

How do I revert to the old behaviour? Or what would be an alternative way to do normal X mouse selection in vim (or other applications that enable the mouse protocol)?

FWIW, I can reproduce even if I disable all customisations I can think of:

xrdb < /dev/null
env -i DISPLAY="$DISPLAY" xterm -class MYXTerm -name myxterm -e \
  vim -u NONE -c 'set mouse=a' -c help

(and try Shift+LeftMouseButton in that vim help screen).

Both with the xterm 361 Debian package and xterm built from source with the default settings.

Edit. After a reboot, the problem went away, but it was because that ended up deactivating NumLock. So, correction: the "problem" only occurs when I have NumLock on.

Best Answer

OP comments:

turns out the "problem" manifests itself only when NumLock (mod2 modifier) is on.

With xterm #361, that is intentional:

amend rule for using shift-key to override mouse-protocol for select/paste to limit that feature to mouse-buttons which are actually bound to select/paste actions

xterm uses the X Toolkit translations resource to bind various keys and mouse (pointer) buttons with modifiers to actions. Most people use the default translations, possibly with a few additions in their X resources. Because the translations feature is relatively static, xterm implements the mouse protocol by inspecting the events seen in the actions used for select/paste:

In #361 (see source), xterm checks the translations resource at startup, to determine which pointer (mouse) buttons are bound to these events, and when a matching button event is received with just the shift-modifier, it will override the mouse protocol and perform the select/paste action (as it has done for quite a while).

The reason for the change was to allow applications to get some combinations (such as shift with the wheel mouse) to receive escape sequences that they could interpret.

The translations resource does not describe this special treatment of shift, e.g., in

                       ~Meta <Btn1Down>:select-start() \n\
                     ~Meta <Btn1Motion>:select-extend() \n\

but xterm's mouse protocol relies upon being able to receive events which are not really explicitly defined in those translations. I noticed after #361 that it did not treat motion events consistently with this altered scheme (and a fix will be in #362).

I generally use xmodmap to define a Meta key, so that I can use those translations. With a display on macOS, I have this:

xmodmap:  up to 2 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x40),  Shift_R (0x44)
lock        Caps_Lock (0x41)
control     Control_L (0x43),  Control_R (0x46)
mod1        Alt_L (0x42),  Alt_R (0x45)
mod2        Meta_L (0x3f),  Meta_R (0x47)
mod3      
mod4      
mod5      

while an unmodified xmodmap displaying on Debian is different:

xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)

so that Meta is accessible in the latter, but less conveniently: it requires a couple of mode-switches.

There are other problem areas to explore, such as a pending pull request don't ignore missing non-standard modifiers in _XtMatchUsingDontCareMods, which would interfere with the use of mod2 for Meta (by eliminating some of those events which xterm converts into escape sequences).

Related Question