Skip to content

Commit e6392b1

Browse files
ychinbrammool
authored andcommitted
patch 9.0.0911: with 'smoothscroll' set mouse click position may be wrong
Problem: With 'smoothscroll' set mouse click position may be wrong. Solution: Adjust computations for w_skipcol. (Yee Cheng Chin, closes #11514)
1 parent c934bfa commit e6392b1

3 files changed

Lines changed: 84 additions & 4 deletions

File tree

src/mouse.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,14 +3034,29 @@ mouse_comp_pos(
30343034
row -= win->w_topfill;
30353035
else
30363036
row -= diff_check_fill(win, lnum);
3037-
count = plines_win_nofill(win, lnum, TRUE);
3037+
count = plines_win_nofill(win, lnum, FALSE);
30383038
}
30393039
else
30403040
#endif
3041-
count = plines_win(win, lnum, TRUE);
3041+
count = plines_win(win, lnum, FALSE);
30423042
if (plines_cache != NULL && cache_idx < Rows)
30433043
plines_cache[cache_idx] = count;
30443044
}
3045+
3046+
if (win->w_skipcol > 0 && lnum == win->w_topline)
3047+
{
3048+
// Adjust for 'smoothscroll' clipping the top screen lines.
3049+
// A similar formula is used in curs_columns().
3050+
int width1 = win->w_width - win_col_off(win);
3051+
int skip_lines = 0;
3052+
if (win->w_skipcol > width1)
3053+
skip_lines = (win->w_skipcol - width1)
3054+
/ (width1 + win_col_off2(win)) + 1;
3055+
else if (win->w_skipcol > 0)
3056+
skip_lines = 1;
3057+
count -= skip_lines;
3058+
}
3059+
30453060
if (count > row)
30463061
break; // Position is in this buffer line.
30473062
#ifdef FEAT_FOLDING
@@ -3063,8 +3078,10 @@ mouse_comp_pos(
30633078
if (col < off)
30643079
col = off;
30653080
col += row * (win->w_width - off);
3066-
// add skip column (for long wrapping line)
3067-
col += win->w_skipcol;
3081+
3082+
// Add skip column for the topline.
3083+
if (lnum == win->w_topline)
3084+
col += win->w_skipcol;
30683085
}
30693086

30703087
if (!win->w_p_wrap)

src/testdir/test_scroll_opt.vim

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
source check.vim
44
source screendump.vim
5+
source mouse.vim
56

67
func Test_reset_scroll()
78
let scr = &l:scroll
@@ -452,5 +453,65 @@ func Test_smoothscroll_cursor_position()
452453
bwipeout!
453454
endfunc
454455

456+
" Test that mouse picking is still accurate when we have smooth scrolled lines
457+
func Test_smoothscroll_mouse_pos()
458+
CheckNotGui
459+
CheckUnix
460+
461+
let save_mouse = &mouse
462+
let save_term = &term
463+
let save_ttymouse = &ttymouse
464+
set mouse=a term=xterm ttymouse=xterm2
465+
466+
call NewWindow(10, 20)
467+
setl smoothscroll wrap
468+
" First line will wrap to 3 physical lines. 2nd/3rd lines are short lines.
469+
call setline(1, ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "line 2", "line 3"])
470+
471+
func s:check_mouse_click(row, col, buf_row, buf_col)
472+
call MouseLeftClick(a:row, a:col)
473+
474+
call assert_equal(a:col, wincol())
475+
call assert_equal(a:row, winline())
476+
call assert_equal(a:buf_row, line('.'))
477+
call assert_equal(a:buf_col, col('.'))
478+
endfunc
479+
480+
" Check that clicking without scroll works first.
481+
call s:check_mouse_click(3, 5, 1, 45)
482+
call s:check_mouse_click(4, 1, 2, 1)
483+
call s:check_mouse_click(4, 6, 2, 6)
484+
call s:check_mouse_click(5, 1, 3, 1)
485+
call s:check_mouse_click(5, 6, 3, 6)
486+
487+
" Smooth scroll, and checks that this didn't mess up mouse clicking
488+
exe "normal \<C-E>"
489+
call s:check_mouse_click(2, 5, 1, 45)
490+
call s:check_mouse_click(3, 1, 2, 1)
491+
call s:check_mouse_click(3, 6, 2, 6)
492+
call s:check_mouse_click(4, 1, 3, 1)
493+
call s:check_mouse_click(4, 6, 3, 6)
494+
495+
exe "normal \<C-E>"
496+
call s:check_mouse_click(1, 5, 1, 45)
497+
call s:check_mouse_click(2, 1, 2, 1)
498+
call s:check_mouse_click(2, 6, 2, 6)
499+
call s:check_mouse_click(3, 1, 3, 1)
500+
call s:check_mouse_click(3, 6, 3, 6)
501+
502+
" Make a new first line 11 physical lines tall so it's taller than window
503+
" height, to test overflow calculations with really long lines wrapping.
504+
normal gg
505+
call setline(1, "12345678901234567890"->repeat(11))
506+
exe "normal 6\<C-E>"
507+
call s:check_mouse_click(5, 1, 1, 201)
508+
call s:check_mouse_click(6, 1, 2, 1)
509+
call s:check_mouse_click(7, 1, 3, 1)
510+
511+
let &mouse = save_mouse
512+
let &term = save_term
513+
let &ttymouse = save_ttymouse
514+
endfunc
515+
455516

456517
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
911,
698700
/**/
699701
910,
700702
/**/

0 commit comments

Comments
 (0)