Mirror of the Vim source from https://github.com/vim/vim
Revision | 7e48ddb8b0799a49a05288a7ad47ad14d675f78b (tree) |
---|---|
Time | 2022-11-19 23:45:03 |
Author | Bram Moolenaar <Bram@vim....> |
Commiter | Bram Moolenaar |
patch 9.0.0911: with 'smoothscroll' set mouse click position may be wrong
Commit: https://github.com/vim/vim/commit/e6392b102151ec69fad232bcf00591230cef8e1c
Author: Yee Cheng Chin <ychin.git@gmail.com>
Date: Sat Nov 19 14:31:08 2022 +0000
@@ -3034,14 +3034,29 @@ | ||
3034 | 3034 | row -= win->w_topfill; |
3035 | 3035 | else |
3036 | 3036 | row -= diff_check_fill(win, lnum); |
3037 | - count = plines_win_nofill(win, lnum, TRUE); | |
3037 | + count = plines_win_nofill(win, lnum, FALSE); | |
3038 | 3038 | } |
3039 | 3039 | else |
3040 | 3040 | #endif |
3041 | - count = plines_win(win, lnum, TRUE); | |
3041 | + count = plines_win(win, lnum, FALSE); | |
3042 | 3042 | if (plines_cache != NULL && cache_idx < Rows) |
3043 | 3043 | plines_cache[cache_idx] = count; |
3044 | 3044 | } |
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 | + | |
3045 | 3060 | if (count > row) |
3046 | 3061 | break; // Position is in this buffer line. |
3047 | 3062 | #ifdef FEAT_FOLDING |
@@ -3063,8 +3078,10 @@ | ||
3063 | 3078 | if (col < off) |
3064 | 3079 | col = off; |
3065 | 3080 | 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; | |
3068 | 3085 | } |
3069 | 3086 | |
3070 | 3087 | if (!win->w_p_wrap) |
@@ -2,6 +2,7 @@ | ||
2 | 2 | |
3 | 3 | source check.vim |
4 | 4 | source screendump.vim |
5 | +source mouse.vim | |
5 | 6 | |
6 | 7 | func Test_reset_scroll() |
7 | 8 | let scr = &l:scroll |
@@ -452,5 +453,65 @@ | ||
452 | 453 | bwipeout! |
453 | 454 | endfunc |
454 | 455 | |
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 | + | |
455 | 516 | |
456 | 517 | " vim: shiftwidth=2 sts=2 expandtab |
@@ -696,6 +696,8 @@ | ||
696 | 696 | static int included_patches[] = |
697 | 697 | { /* Add new patch number below this line */ |
698 | 698 | /**/ |
699 | + 911, | |
700 | +/**/ | |
699 | 701 | 910, |
700 | 702 | /**/ |
701 | 703 | 909, |