To: vim_dev@googlegroups.com Cc: "Paul \"LeoNerd\" Evans" Subject: Patch 8.2.1108 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1108 Problem: Mouse left-right scroll is not supported in terminal window. Solution: Implement mouse codes 6 and 7. (Trygve Aaberge, closes #6363) Files: src/libvterm/src/mouse.c, src/mouse.c, src/terminal.c, src/testdir/mouse.vim, src/testdir/test_termcodes.vim *** ../vim-8.2.1107/src/libvterm/src/mouse.c 2020-05-22 22:06:02.165271263 +0200 --- src/libvterm/src/mouse.c 2020-07-01 15:29:04.147793843 +0200 *************** *** 83,89 **** state->mouse_buttons &= ~(1 << (button-1)); } ! /* Most of the time we don't get button releases from 4/5 */ if(state->mouse_buttons == old_buttons && button < 4) return; if (!(state->mouse_flags & MOUSE_WANT_CLICK)) --- 83,89 ---- state->mouse_buttons &= ~(1 << (button-1)); } ! /* 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,98 **** if(button < 4) { output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row); } ! else if(button < 6) { output_mouse(state, button-4 + 0x40, pressed, mod, state->mouse_col, state->mouse_row); } } --- 92,98 ---- if(button < 4) { output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row); } ! else if(button < 8) { output_mouse(state, button-4 + 0x40, pressed, mod, state->mouse_col, state->mouse_row); } } *** ../vim-8.2.1107/src/mouse.c 2020-02-26 16:15:31.072386953 +0100 --- src/mouse.c 2020-07-01 15:36:24.516992257 +0200 *************** *** 2119,2124 **** --- 2119,2125 ---- # 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,2139 **** long timediff; // elapsed time in msec # endif ! is_click = is_drag = FALSE; # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE) --- 2134,2140 ---- long timediff; // elapsed time in msec # endif ! 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,2264 **** || 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; --- 2257,2262 ---- *************** *** 2270,2275 **** --- 2268,2286 ---- *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,2337 **** # ifdef FEAT_XCLIPBOARD else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK)) { ! if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE) stop_xterm_trace(); else start_xterm_trace(mouse_code); --- 2342,2348 ---- # ifdef FEAT_XCLIPBOARD else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK)) { ! if (is_release) stop_xterm_trace(); else start_xterm_trace(mouse_code); *************** *** 2469,2480 **** if (button & 16) mouse_code |= MOUSE_CTRL; break; case 'u': // Button Up if (button & 1) ! mouse_code |= MOUSE_LEFT | MOUSE_RELEASE; if (button & 2) ! mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE; if (button & 4) ! mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE; if (button & 8) mouse_code |= MOUSE_SHIFT; if (button & 16) --- 2480,2492 ---- if (button & 16) mouse_code |= MOUSE_CTRL; break; case 'u': // Button Up + is_release = TRUE; if (button & 1) ! mouse_code |= MOUSE_LEFT; if (button & 2) ! mouse_code |= MOUSE_MIDDLE; if (button & 4) ! mouse_code |= MOUSE_RIGHT; if (button & 8) mouse_code |= MOUSE_SHIFT; if (button & 16) *************** *** 2598,2614 **** case 2: mouse_code = MOUSE_LEFT; WantQueryMouse = TRUE; break; ! case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT; break; case 4: mouse_code = MOUSE_MIDDLE; WantQueryMouse = TRUE; break; ! case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE; break; case 6: mouse_code = MOUSE_RIGHT; WantQueryMouse = TRUE; break; ! case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT; break; case 8: return -1; // fourth button down case 9: return -1; // fourth button up --- 2610,2629 ---- case 2: mouse_code = MOUSE_LEFT; WantQueryMouse = TRUE; break; ! case 3: mouse_code = MOUSE_LEFT; ! is_release = TRUE; break; case 4: mouse_code = MOUSE_MIDDLE; WantQueryMouse = TRUE; break; ! case 5: mouse_code = MOUSE_MIDDLE; ! is_release = TRUE; break; case 6: mouse_code = MOUSE_RIGHT; WantQueryMouse = TRUE; break; ! 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,2667 **** break; case 32: // Release ! mouse_code |= MOUSE_RELEASE; break; case 33: // Drag --- 2676,2682 ---- break; case 32: // Release ! is_release = TRUE; break; case 33: // Drag *************** *** 2682,2687 **** --- 2697,2705 ---- // 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,2800 **** // 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 & 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; held_button = MOUSE_RELEASE; } else --- 2804,2825 ---- // 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 && (!is_release || release_is_ambiguous)) { if (wheel_code & MOUSE_CTRL) *modifiers |= MOD_MASK_CTRL; if (wheel_code & MOUSE_ALT) *modifiers |= MOD_MASK_ALT; ! ! 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 *** ../vim-8.2.1107/src/terminal.c 2020-06-12 22:59:07.274097177 +0200 --- src/terminal.c 2020-07-01 15:29:04.147793843 +0200 *************** *** 1389,1396 **** 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_LEFTMOUSE: case K_LEFTMOUSE_NM: --- 1389,1396 ---- 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: 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,2479 **** --- 2474,2481 ---- 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 *** ../vim-8.2.1107/src/testdir/mouse.vim 2020-03-22 14:08:27.321399669 +0100 --- src/testdir/mouse.vim 2020-07-01 15:29:04.147793843 +0200 *************** *** 169,172 **** --- 169,188 ---- 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 *** ../vim-8.2.1107/src/testdir/test_termcodes.vim 2020-06-14 14:34:13.337463441 +0200 --- src/testdir/test_termcodes.vim 2020-07-01 15:29:04.147793843 +0200 *************** *** 194,202 **** new let save_mouse = &mouse let save_term = &term let save_ttymouse = &ttymouse ! set mouse=a term=xterm ! call setline(1, range(1, 100)) for ttymouse_val in g:Ttymouse_values let msg = 'ttymouse=' .. ttymouse_val --- 194,203 ---- new let save_mouse = &mouse let save_term = &term + let save_wrap = &wrap let save_ttymouse = &ttymouse ! 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,229 **** --- 221,251 ---- 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 *** ../vim-8.2.1107/src/version.c 2020-07-01 15:12:39.715774200 +0200 --- src/version.c 2020-07-01 15:34:57.353526278 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1108, /**/ -- If you don't get everything you want, think of everything you didn't get and don't want. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///