From 7dd51d35426b183aa5030f62f8b7e022943332eb Mon Sep 17 00:00:00 2001 From: notuxic Date: Tue, 11 Nov 2025 17:52:45 +0000 Subject: [PATCH] patch 9.1.1907: xterm: no support for mouse buttons 8 and 9 Problem: xterm: no support for mouse buttons 8 and 9 Solution: Add support for terminals with xterm-like mouse functionality (notuxic) closes: #18719 Signed-off-by: notuxic Signed-off-by: Christian Brabandt --- runtime/doc/term.txt | 5 +-- src/mouse.c | 12 +++++++- src/testdir/test_termcodes.vim | 56 ++++++++++++++++++++++++++++++++++ src/version.c | 2 ++ src/vim.h | 3 ++ 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt index 784105fe6e..4504c62d31 100644 --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -1,4 +1,4 @@ -*term.txt* For Vim version 9.1. Last change: 2025 Nov 09 +*term.txt* For Vim version 9.1. Last change: 2025 Nov 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1167,7 +1167,8 @@ Mouse clicks can be mapped. The codes for mouse clicks are: The X1 and X2 buttons refer to the extra buttons found on some mice. The 'Microsoft Explorer' mouse has these buttons available to the right thumb. -Currently X1 and X2 only work on Win32 and X11 environments. +Currently, X1 and X2 work only on Win32 and X11 environments, and in terminals +that support xterm-like mouse functionality. Examples: > :noremap diff --git a/src/mouse.c b/src/mouse.c index 4bd1e592fc..d11491005c 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -2316,6 +2316,10 @@ check_termcode_mouse( * 0x23 = any button release * 0x60 = button 4 down (scroll wheel down) * 0x61 = button 5 down (scroll wheel up) + * 0x62 = button 6 down (scroll wheel left) + * 0x63 = button 7 down (scroll wheel right) + * 0xa0 = button 8 down (backward button) + * 0xa1 = button 9 down (forward button) * add 0x04 for SHIFT * add 0x08 for ALT * add 0x10 for CTRL @@ -2470,7 +2474,7 @@ check_termcode_mouse( * Linux console with GPM and the MS-DOS or Win32 console * (multi-clicks use >= 0x60). */ - if (mouse_code >= MOUSEWHEEL_LOW + if (mouse_code >= MOUSEWHEEL_LOW && mouse_code < MOUSESIDEBUTTONS_LOW # ifdef FEAT_GUI && !gui.in_use # endif @@ -2993,7 +2997,13 @@ check_termcode_mouse( held_button = MOUSE_RELEASE; } else + { +#if defined(UNIX) + if (use_xterm_mouse() && orig_mouse_code >= MOUSESIDEBUTTONS_LOW) + current_button = (current_button) ? MOUSE_X2 : MOUSE_X1; +#endif key_name[1] = get_pseudo_mouse_code(current_button, is_click, is_drag); + } // Make sure the mouse position is valid. Some terminals may return weird diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim index 652a1bf8c1..ffe3576ff0 100644 --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -1641,6 +1641,62 @@ func Test_mouse_termcodes() %bw! endfunc +" Test buttons 8 and 9 for xterm-like terminal mouse support +func Test_term_mouse_side_buttons() + new + let save_mouse = &mouse + let save_term = &term + let save_ttymouse = &ttymouse + call test_override('no_query_mouse', 1) + set mouse=a term=xterm + call WaitForResponses() + + for ttymouse_val in g:Ttymouse_values + let msg = 'ttymouse=' .. ttymouse_val + exe 'set ttymouse=' .. ttymouse_val + + let mouse_codes = [ + \ ["", TerminalEscapeCode(128, 1, 1, 'M')], + \ ["", TerminalEscapeCode(128+32, 1, 1, 'M')], + \ ["", TerminalEscapeCode(129, 1, 1, 'M')], + \ ["", TerminalEscapeCode(129+32, 1, 1, 'M')], + \ ["", TerminalEscapeCode(128+4, 1, 1, 'M')], + \ ["", TerminalEscapeCode(129+4, 1, 1, 'M')], + \ ["", TerminalEscapeCode(128+8, 1, 1, 'M')], + \ ["", TerminalEscapeCode(129+8, 1, 1, 'M')], + \ ["", TerminalEscapeCode(128+16, 1, 1, 'M')], + \ ["", TerminalEscapeCode(129+16, 1, 1, 'M')], + \ ] + + for [outstr, code] in mouse_codes + exe "normal ggC\" . code + call assert_equal(outstr, getline(1), msg) + endfor + endfor + + " ttymouse_val 'sgr' + let msg = 'ttymouse=sgr' + exe 'set ttymouse=sgr' + + let mouse_codes = [ + \ ["", TerminalEscapeCode(128, 1, 1, 'M')], + \ ["", TerminalEscapeCode(128, 1, 1, 'm')], + \ ["", TerminalEscapeCode(129, 1, 1, 'M')], + \ ["", TerminalEscapeCode(129, 1, 1, 'm')], + \ ] + + for [outstr, code] in mouse_codes + exe "normal ggC\" . code + call assert_equal(outstr, getline(1), msg) + endfor + + let &mouse = save_mouse + let &term = save_term + let &ttymouse = save_ttymouse + call test_override('no_query_mouse', 0) + bwipe! +endfunc + " This only checks if the sequence is recognized. " This must be after other tests, because it has side effects to xterm " properties. diff --git a/src/version.c b/src/version.c index acb1c5d7cb..5578ccfc62 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1907, /**/ 1906, /**/ diff --git a/src/vim.h b/src/vim.h index 58823ec786..e41a68f1c2 100644 --- a/src/vim.h +++ b/src/vim.h @@ -2095,6 +2095,9 @@ typedef int sock_T; // Lowest button code for using the mouse wheel (xterm only) #define MOUSEWHEEL_LOW 0x60 +// Lowest button code for extra mouse buttons 8-11 +#define MOUSESIDEBUTTONS_LOW 0xa0 + #define MOUSE_CLICK_MASK 0x03 #define NUM_MOUSE_CLICKS(code) \