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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202007011350.061DoTC91172052%40masaka.moolenaar.net.

Raspunde prin e-mail lui