# HG changeset patch # User Bram Moolenaar # Date 1596984304 -7200 # Node ID b997e872ff955201d950083cb4a0422d581c6f60 # Parent 5294e38bd231384750bd4f3d9c6c0734578602a3 patch 8.2.1406: popupwindow lacks scrollbar if no "maxheight" is used Commit: https://github.com/vim/vim/commit/a1b9b0cc011ef15869ac25cb93e1b4baa0cb7f38 Author: Bram Moolenaar Date: Sun Aug 9 16:37:48 2020 +0200 patch 8.2.1406: popupwindow lacks scrollbar if no "maxheight" is used Problem: Popupwindow lacks scrollbar if no "maxheight" is used. Solution: Compute the max height depending on the position. (closes https://github.com/vim/vim/issues/6664) diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -1130,6 +1130,7 @@ popup_adjust_position(win_T *wp) int org_leftcol = wp->w_leftcol; int org_leftoff = wp->w_popup_leftoff; int minwidth, minheight; + int maxheight = Rows; int wantline = wp->w_wantline; // adjusted for textprop int wantcol = wp->w_wantcol; // adjusted for textprop int use_wantcol = wantcol != 0; @@ -1277,6 +1278,9 @@ popup_adjust_position(win_T *wp) } #endif + if (wp->w_maxheight > 0) + maxheight = wp->w_maxheight; + // start at the desired first line if (wp->w_firstline > 0) wp->w_topline = wp->w_firstline; @@ -1353,11 +1357,11 @@ popup_adjust_position(win_T *wp) ++lnum; // do not use the width of lines we're not going to show - if (wp->w_maxheight > 0 + if (maxheight > 0 && (wp->w_firstline >= 0 ? lnum - wp->w_topline : wp->w_buffer->b_ml.ml_line_count - lnum) - + wrapped >= wp->w_maxheight) + + wrapped >= maxheight) break; } @@ -1449,13 +1453,11 @@ popup_adjust_position(win_T *wp) + 1 + wrapped; if (minheight > 0 && wp->w_height < minheight) wp->w_height = minheight; - if (wp->w_maxheight > 0 && wp->w_height > wp->w_maxheight) - wp->w_height = wp->w_maxheight; + if (maxheight > 0 && wp->w_height > maxheight) + wp->w_height = maxheight; w_height_before_limit = wp->w_height; if (wp->w_height > Rows - wp->w_winrow) wp->w_height = Rows - wp->w_winrow; - if (wp->w_height != org_height) - win_comp_scroll(wp); if (center_vert) { @@ -1477,9 +1479,21 @@ popup_adjust_position(win_T *wp) wp->w_height = wantline - extra_height; } else + { // Not enough space and more space on the other side: make top // aligned. wp->w_winrow = (wantline < 0 ? 0 : wantline) + 1; + if (wp->w_winrow + wp->w_height + extra_height >= Rows) + { + wp->w_height = Rows - wp->w_winrow - extra_height; + if (wp->w_want_scrollbar +#ifdef FEAT_TERMINAL + && wp->w_buffer->b_term == NULL +#endif + ) + wp->w_has_scrollbar = TRUE; + } + } } else if (wp->w_popup_pos == POPPOS_TOPRIGHT || wp->w_popup_pos == POPPOS_TOPLEFT) @@ -1501,11 +1515,15 @@ popup_adjust_position(win_T *wp) else wp->w_winrow = wantline - 1; } + // make sure w_window is valid if (wp->w_winrow >= Rows) wp->w_winrow = Rows - 1; else if (wp->w_winrow < 0) wp->w_winrow = 0; + if (wp->w_height != org_height) + win_comp_scroll(wp); + wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer); if (win_valid(wp->w_popup_prop_win)) { diff --git a/src/testdir/dumps/Test_popupwin_toohigh_1.dump b/src/testdir/dumps/Test_popupwin_toohigh_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_toohigh_1.dump @@ -0,0 +1,10 @@ +|1+0&#ffffff0@9| @64 +|2@9| @64 +|3@8>3| @64 +|4@8|╔+0#0000001#ffd7ff255|═@8|╗| +0#0000000#ffffff0@54 +|5@8|║+0#0000001#ffd7ff255|o|n|e| @4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|6@8|║+0#0000001#ffd7ff255|t|w|o| @4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|7@8|║+0#0000001#ffd7ff255|t|h|r|e@1| @2| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|8@8|║+0#0000001#ffd7ff255|f|o|u|r| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|9@8|║+0#0000001#ffd7ff255|f|i|v|e| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +@9|╚+0#0000001#ffd7ff255|═@8|╝| +0#0000000#ffffff0@36|3|,|1|0| @9|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_toohigh_2.dump b/src/testdir/dumps/Test_popupwin_toohigh_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_toohigh_2.dump @@ -0,0 +1,10 @@ +|1+0&#ffffff0@8|╔+0#0000001#ffd7ff255|═@8|╗| +0#0000000#ffffff0@54 +|2@8|║+0#0000001#ffd7ff255|o|n|e| @4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|3@8|║+0#0000001#ffd7ff255|t|w|o| @4| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|4@8|║+0#0000001#ffd7ff255|t|h|r|e@1| @2| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|5@8|║+0#0000001#ffd7ff255|f|o|u|r| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|6@8|║+0#0000001#ffd7ff255|f|i|v|e| @3| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@54 +|7@8|╚+0#0000001#ffd7ff255|═@8|╝| +0#0000000#ffffff0@54 +|8@8>8| @64 +|9@9| @64 +|:|c|a|l@1| |S|h|o|w|P|o|p|u|p|(|)| @39|8|,|1|0| @9|T|o|p| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -2144,6 +2144,36 @@ func Test_popup_scrollbar() call delete('XtestPopupScroll') endfunc +func Test_popup_too_high_scrollbar() + CheckScreendump + + let lines =<< trim END + call setline(1, range(1, 20)->map({i, v -> repeat(v, 10)})) + set scrolloff=0 + func ShowPopup() + let winid = popup_atcursor(['one', 'two', 'three', 'four', 'five', + \ 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve'], #{ + \ minwidth: 8, + \ border: [], + \ }) + endfunc + normal 3G$ + call ShowPopup() + END + call writefile(lines, 'XtestPopupToohigh') + let buf = RunVimInTerminal('-S XtestPopupToohigh', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_toohigh_1', {}) + + call term_sendkeys(buf, ":call popup_clear()\") + call term_sendkeys(buf, "8G$") + call term_sendkeys(buf, ":call ShowPopup()\") + call VerifyScreenDump(buf, 'Test_popupwin_toohigh_2', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestPopupToohigh') +endfunc + func Test_popup_fitting_scrollbar() " this was causing a crash, divide by zero let winid = popup_create([ diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1406, +/**/ 1405, /**/ 1404,