]> granicus.if.org Git - vim/commitdiff
patch 9.0.0911: with 'smoothscroll' set mouse click position may be wrong v9.0.0911
authorYee Cheng Chin <ychin.git@gmail.com>
Sat, 19 Nov 2022 14:31:08 +0000 (14:31 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 19 Nov 2022 14:31:08 +0000 (14:31 +0000)
Problem:    With 'smoothscroll' set mouse click position may be wrong.
Solution:   Adjust computations for w_skipcol. (Yee Cheng Chin, closes #11514)

src/mouse.c
src/testdir/test_scroll_opt.vim
src/version.c

index 98e05955eb35ca0970de7538ec53524240b1b462..32407eb394f532e3a2ed99853077cc145be212d3 100644 (file)
@@ -3034,14 +3034,29 @@ mouse_comp_pos(
                    row -= win->w_topfill;
                else
                    row -= diff_check_fill(win, lnum);
-               count = plines_win_nofill(win, lnum, TRUE);
+               count = plines_win_nofill(win, lnum, FALSE);
            }
            else
 #endif
-               count = plines_win(win, lnum, TRUE);
+               count = plines_win(win, lnum, FALSE);
            if (plines_cache != NULL && cache_idx < Rows)
                plines_cache[cache_idx] = count;
        }
+
+       if (win->w_skipcol > 0 && lnum == win->w_topline)
+       {
+           // Adjust for 'smoothscroll' clipping the top screen lines.
+           // A similar formula is used in curs_columns().
+           int width1 = win->w_width - win_col_off(win);
+           int skip_lines = 0;
+           if (win->w_skipcol > width1)
+               skip_lines = (win->w_skipcol - width1)
+                                           / (width1 + win_col_off2(win)) + 1;
+           else if (win->w_skipcol > 0)
+               skip_lines = 1;
+           count -= skip_lines;
+       }
+
        if (count > row)
            break;      // Position is in this buffer line.
 #ifdef FEAT_FOLDING
@@ -3063,8 +3078,10 @@ mouse_comp_pos(
        if (col < off)
            col = off;
        col += row * (win->w_width - off);
-       // add skip column (for long wrapping line)
-       col += win->w_skipcol;
+
+       // Add skip column for the topline.
+       if (lnum == win->w_topline)
+           col += win->w_skipcol;
     }
 
     if (!win->w_p_wrap)
index d40c650f3ca89af867a430a45f83b22dfce3a9ce..96afce068fcc3be9b882fc78d5d148abf449a1a3 100644 (file)
@@ -2,6 +2,7 @@
 
 source check.vim
 source screendump.vim
+source mouse.vim
 
 func Test_reset_scroll()
   let scr = &l:scroll
@@ -452,5 +453,65 @@ func Test_smoothscroll_cursor_position()
   bwipeout!
 endfunc
 
+" Test that mouse picking is still accurate when we have smooth scrolled lines
+func Test_smoothscroll_mouse_pos()
+  CheckNotGui
+  CheckUnix
+
+  let save_mouse = &mouse
+  let save_term = &term
+  let save_ttymouse = &ttymouse
+  set mouse=a term=xterm ttymouse=xterm2
+
+  call NewWindow(10, 20)
+  setl smoothscroll wrap
+  " First line will wrap to 3 physical lines. 2nd/3rd lines are short lines.
+  call setline(1, ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "line 2", "line 3"])
+
+  func s:check_mouse_click(row, col, buf_row, buf_col)
+    call MouseLeftClick(a:row, a:col)
+
+    call assert_equal(a:col, wincol())
+    call assert_equal(a:row, winline())
+    call assert_equal(a:buf_row, line('.'))
+    call assert_equal(a:buf_col, col('.'))
+  endfunc
+
+  " Check that clicking without scroll works first.
+  call s:check_mouse_click(3, 5, 1, 45)
+  call s:check_mouse_click(4, 1, 2, 1)
+  call s:check_mouse_click(4, 6, 2, 6)
+  call s:check_mouse_click(5, 1, 3, 1)
+  call s:check_mouse_click(5, 6, 3, 6)
+
+  " Smooth scroll, and checks that this didn't mess up mouse clicking
+  exe "normal \<C-E>"
+  call s:check_mouse_click(2, 5, 1, 45)
+  call s:check_mouse_click(3, 1, 2, 1)
+  call s:check_mouse_click(3, 6, 2, 6)
+  call s:check_mouse_click(4, 1, 3, 1)
+  call s:check_mouse_click(4, 6, 3, 6)
+
+  exe "normal \<C-E>"
+  call s:check_mouse_click(1, 5, 1, 45)
+  call s:check_mouse_click(2, 1, 2, 1)
+  call s:check_mouse_click(2, 6, 2, 6)
+  call s:check_mouse_click(3, 1, 3, 1)
+  call s:check_mouse_click(3, 6, 3, 6)
+
+  " Make a new first line 11 physical lines tall so it's taller than window
+  " height, to test overflow calculations with really long lines wrapping.
+  normal gg
+  call setline(1, "12345678901234567890"->repeat(11))
+  exe "normal 6\<C-E>"
+  call s:check_mouse_click(5, 1, 1, 201)
+  call s:check_mouse_click(6, 1, 2, 1)
+  call s:check_mouse_click(7, 1, 3, 1)
+
+  let &mouse = save_mouse
+  let &term = save_term
+  let &ttymouse = save_ttymouse
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
index e9b0431458b09f02beacdf7f6a8637527f7c769c..292d02276b04bfa62ede7e7f935a411c775dc8f0 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    911,
 /**/
     910,
 /**/