]> granicus.if.org Git - vim/commitdiff
patch 8.2.1108: mouse left-right scroll is not supported in terminal window v8.2.1108
authorBram Moolenaar <Bram@vim.org>
Wed, 1 Jul 2020 13:49:29 +0000 (15:49 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 1 Jul 2020 13:49:29 +0000 (15:49 +0200)
Problem:    Mouse left-right scroll is not supported in terminal window.
Solution:   Implement mouse codes 6 and 7. (Trygve Aaberge, closes #6363)

src/libvterm/src/mouse.c
src/mouse.c
src/terminal.c
src/testdir/mouse.vim
src/testdir/test_termcodes.vim
src/version.c

index 4e363134eb1eb4eb5182d1763b7be42a91203d78..ed60b0147d79e758a41746b3efc5e795bfb9282b 100644 (file)
@@ -83,7 +83,7 @@ void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod)
       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 button, int pressed, VTermModifier mod)
   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);
   }
 }
index 5abb94221c7bafd820fa5700418554ebdd4594e8..143bcf2f67cb92d77a25c8b4dff1178a4fb7dc91 100644 (file)
@@ -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
index 5424574868d0d49bbecf1236978a77571ee780b3..bd5fd41ee73b5af7ad0d6e9f265363a9ffe7e09f 100644 (file)
@@ -1389,8 +1389,8 @@ term_convert_key(term_T *term, int c, int modmask, char *buf)
 
        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
index a28a439c19d244fd024c0243069099c44f9ae7d2..5eab1de48f2b1b6b657b214c2c0204d4c4b8acc6 100644 (file)
@@ -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
index 27c2a18cf8b4b9fc449b187f84f5dc19d7613b7e..a267696cc1aee532d13062d6815c0cde46860180 100644 (file)
@@ -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(1100))
+  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
index 97c3c4ca621e0f4d4f316745224d0ad2406a8929..2691996ad8c7e96ecc25f4d6e845363f006de9ce 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1108,
 /**/
     1107,
 /**/