# HG changeset patch # User Bram Moolenaar # Date 1593612005 -7200 # Node ID d0265fdadec95a19f7bbbc34d78bd5faf32cd926 # Parent e0f65780cc0ab728d2897a5b8c901e7466033b1e patch 8.2.1108: mouse left-right scroll is not supported in terminal window Commit: https://github.com/vim/vim/commit/d58d4f90aeb381045000ea46493b5bd9b9d1fa23 Author: Bram Moolenaar Date: Wed Jul 1 15:49:29 2020 +0200 patch 8.2.1108: mouse left-right scroll is not supported in terminal window Problem: Mouse left-right scroll is not supported in terminal window. Solution: Implement mouse codes 6 and 7. (Trygve Aaberge, closes https://github.com/vim/vim/issues/6363) diff --git a/src/libvterm/src/mouse.c b/src/libvterm/src/mouse.c --- a/src/libvterm/src/mouse.c +++ b/src/libvterm/src/mouse.c @@ -83,7 +83,7 @@ void vterm_mouse_button(VTerm *vt, int b state->mouse_buttons &= ~(1 << (button-1)); } - /* Most of the time we don't get button releases from 4/5 */ + /* Most of the time we don't get button releases from 4/5/6/7 */ if(state->mouse_buttons == old_buttons && button < 4) return; if (!(state->mouse_flags & MOUSE_WANT_CLICK)) @@ -92,7 +92,7 @@ void vterm_mouse_button(VTerm *vt, int b if(button < 4) { output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row); } - else if(button < 6) { + else if(button < 8) { output_mouse(state, button-4 + 0x40, pressed, mod, state->mouse_col, state->mouse_row); } } diff --git a/src/mouse.c b/src/mouse.c --- a/src/mouse.c +++ b/src/mouse.c @@ -2119,6 +2119,7 @@ check_termcode_mouse( # endif int mouse_code = 0; // init for GCC int is_click, is_drag; + int is_release, release_is_ambiguous; int wheel_code = 0; int current_button; static int held_button = MOUSE_RELEASE; @@ -2133,7 +2134,7 @@ check_termcode_mouse( long timediff; // elapsed time in msec # endif - is_click = is_drag = FALSE; + is_click = is_drag = is_release = release_is_ambiguous = FALSE; # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE) @@ -2256,9 +2257,6 @@ check_termcode_mouse( || key_name[0] == KS_SGR_MOUSE_RELEASE) mouse_code += 32; - if (key_name[0] == KS_SGR_MOUSE_RELEASE) - mouse_code |= MOUSE_RELEASE; - mouse_col = getdigits(&p) - 1; if (*p++ != ';') return -1; @@ -2270,6 +2268,19 @@ check_termcode_mouse( *modifiers = 0; } + if (key_name[0] == KS_SGR_MOUSE + || key_name[0] == KS_SGR_MOUSE_RELEASE) + { + if (key_name[0] == KS_SGR_MOUSE_RELEASE) + is_release = TRUE; + } + else + { + release_is_ambiguous = TRUE; + if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE) + is_release = TRUE; + } + if (key_name[0] == KS_MOUSE # ifdef FEAT_MOUSE_GPM || key_name[0] == KS_GPM_MOUSE @@ -2331,7 +2342,7 @@ check_termcode_mouse( # ifdef FEAT_XCLIPBOARD else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK)) { - if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE) + if (is_release) stop_xterm_trace(); else start_xterm_trace(mouse_code); @@ -2469,12 +2480,13 @@ check_termcode_mouse( if (button & 16) mouse_code |= MOUSE_CTRL; break; case 'u': // Button Up + is_release = TRUE; if (button & 1) - mouse_code |= MOUSE_LEFT | MOUSE_RELEASE; + mouse_code |= MOUSE_LEFT; if (button & 2) - mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE; + mouse_code |= MOUSE_MIDDLE; if (button & 4) - mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE; + mouse_code |= MOUSE_RIGHT; if (button & 8) mouse_code |= MOUSE_SHIFT; if (button & 16) @@ -2598,17 +2610,20 @@ check_termcode_mouse( case 2: mouse_code = MOUSE_LEFT; WantQueryMouse = TRUE; break; - case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT; + case 3: mouse_code = MOUSE_LEFT; + is_release = TRUE; break; case 4: mouse_code = MOUSE_MIDDLE; WantQueryMouse = TRUE; break; - case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE; + case 5: mouse_code = MOUSE_MIDDLE; + is_release = TRUE; break; case 6: mouse_code = MOUSE_RIGHT; WantQueryMouse = TRUE; break; - case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT; + case 7: mouse_code = MOUSE_RIGHT; + is_release = TRUE; break; case 8: return -1; // fourth button down case 9: return -1; // fourth button up @@ -2661,7 +2676,7 @@ check_termcode_mouse( break; case 32: // Release - mouse_code |= MOUSE_RELEASE; + is_release = TRUE; break; case 33: // Drag @@ -2682,6 +2697,9 @@ check_termcode_mouse( // Interpret the mouse code current_button = (mouse_code & MOUSE_CLICK_MASK); + if (is_release) + current_button |= MOUSE_RELEASE; + if (current_button == MOUSE_RELEASE # ifdef FEAT_MOUSE_XTERM && wheel_code == 0 @@ -2786,15 +2804,22 @@ check_termcode_mouse( // Work out our pseudo mouse event. Note that MOUSE_RELEASE gets // added, then it's not mouse up/down. key_name[0] = KS_EXTRA; - if (wheel_code != 0 - && (wheel_code & MOUSE_RELEASE) != MOUSE_RELEASE) + if (wheel_code != 0 && (!is_release || release_is_ambiguous)) { if (wheel_code & MOUSE_CTRL) *modifiers |= MOD_MASK_CTRL; if (wheel_code & MOUSE_ALT) *modifiers |= MOD_MASK_ALT; - key_name[1] = (wheel_code & 1) - ? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN; + + if (wheel_code & 1 && wheel_code & 2) + key_name[1] = (int)KE_MOUSELEFT; + else if (wheel_code & 2) + key_name[1] = (int)KE_MOUSERIGHT; + else if (wheel_code & 1) + key_name[1] = (int)KE_MOUSEUP; + else + key_name[1] = (int)KE_MOUSEDOWN; + held_button = MOUSE_RELEASE; } else diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -1389,8 +1389,8 @@ term_convert_key(term_T *term, int c, in case K_MOUSEUP: other = term_send_mouse(vterm, 5, 1); break; case K_MOUSEDOWN: other = term_send_mouse(vterm, 4, 1); break; - case K_MOUSELEFT: /* TODO */ return 0; - case K_MOUSERIGHT: /* TODO */ return 0; + case K_MOUSELEFT: other = term_send_mouse(vterm, 7, 1); break; + case K_MOUSERIGHT: other = term_send_mouse(vterm, 6, 1); break; case K_LEFTMOUSE: case K_LEFTMOUSE_NM: @@ -2474,6 +2474,8 @@ terminal_loop(int blocking) restore_cursor = TRUE; raw_c = term_vgetc(); +if (raw_c > 0) + ch_log(NULL, "terminal_loop() got %d", raw_c); if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) { // Job finished while waiting for a character. Push back the diff --git a/src/testdir/mouse.vim b/src/testdir/mouse.vim --- a/src/testdir/mouse.vim +++ b/src/testdir/mouse.vim @@ -169,4 +169,20 @@ func MouseWheelDown(row, col) call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!') endfunc +func MouseWheelLeftCode(row, col) + return TerminalEscapeCode(0x42, a:row, a:col, 'M') +endfunc + +func MouseWheelLeft(row, col) + call feedkeys(MouseWheelLeftCode(a:row, a:col), 'Lx!') +endfunc + +func MouseWheelRightCode(row, col) + return TerminalEscapeCode(0x43, a:row, a:col, 'M') +endfunc + +func MouseWheelRight(row, col) + call feedkeys(MouseWheelRightCode(a:row, a:col), 'Lx!') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -194,9 +194,10 @@ func Test_1xterm_mouse_wheel() new let save_mouse = &mouse let save_term = &term + let save_wrap = &wrap let save_ttymouse = &ttymouse - set mouse=a term=xterm - call setline(1, range(1, 100)) + set mouse=a term=xterm nowrap + call setline(1, range(100000000000000, 100000000000100)) for ttymouse_val in g:Ttymouse_values let msg = 'ttymouse=' .. ttymouse_val @@ -220,10 +221,31 @@ func Test_1xterm_mouse_wheel() call MouseWheelUp(1, 1) call assert_equal(1, line('w0'), msg) call assert_equal([0, 7, 1, 0], getpos('.'), msg) + + if has('gui') + " Horizontal wheel scrolling currently only works when vim is + " compiled with gui enabled. + call MouseWheelRight(1, 1) + call assert_equal(7, 1 + virtcol(".") - wincol(), msg) + call assert_equal([0, 7, 7, 0], getpos('.'), msg) + + call MouseWheelRight(1, 1) + call assert_equal(13, 1 + virtcol(".") - wincol(), msg) + call assert_equal([0, 7, 13, 0], getpos('.'), msg) + + call MouseWheelLeft(1, 1) + call assert_equal(7, 1 + virtcol(".") - wincol(), msg) + call assert_equal([0, 7, 13, 0], getpos('.'), msg) + + call MouseWheelLeft(1, 1) + call assert_equal(1, 1 + virtcol(".") - wincol(), msg) + call assert_equal([0, 7, 13, 0], getpos('.'), msg) + endif endfor let &mouse = save_mouse let &term = save_term + let &wrap = save_wrap let &ttymouse = save_ttymouse bwipe! endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1108, +/**/ 1107, /**/ 1106,