From 38315295efe43ec3a8e26d6428f819337519f13b Mon Sep 17 00:00:00 2001 From: glepnir Date: Wed, 20 Aug 2025 21:43:15 +0200 Subject: [PATCH] patch 9.1.1660: popups without decoration are positioned wrong at bottom of screen Problem: Popups without border/padding/title don't flip position when cursor is near bottom of screen, while decorated popups do flip correctly. Solution: Use original height instead of truncated height for position inversion check, except for info popups to preserve existing behavior (glepnir). fixes: #12546 closes: #18054 Signed-off-by: glepnir Signed-off-by: Christian Brabandt --- src/popupwin.c | 11 ++--- ...in_bottom_position_without_decoration.dump | 20 ++++++++ src/testdir/test_popupwin.vim | 49 +++++++++++++++++++ src/version.c | 2 + 4 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/testdir/dumps/Test_popupwin_bottom_position_without_decoration.dump diff --git a/src/popupwin.c b/src/popupwin.c index 2f956a3adb..179fc7a1d3 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -1536,11 +1536,7 @@ popup_adjust_position(win_T *wp) if (wp->w_has_scrollbar && wp->w_minwidth > 0) { int off = wp->w_width - maxwidth; - - if (off > right_extra) - extra_width -= right_extra; - else - extra_width -= off; + extra_width -= MIN(off, right_extra); wp->w_width = maxwidth_no_scrollbar; } else @@ -1637,8 +1633,11 @@ popup_adjust_position(win_T *wp) else if (wp->w_popup_pos == POPPOS_TOPRIGHT || wp->w_popup_pos == POPPOS_TOPLEFT) { + + int check_height = (wp->w_popup_flags & POPF_INFO) ? wp->w_height + : w_height_before_limit; if (wp != popup_dragwin - && wantline + (wp->w_height + extra_height) - 1 > Rows + && wantline + (check_height + extra_height) - 1 > Rows && wantline * 2 > Rows && (wp->w_popup_flags & POPF_POSINVERT)) { diff --git a/src/testdir/dumps/Test_popupwin_bottom_position_without_decoration.dump b/src/testdir/dumps/Test_popupwin_bottom_position_without_decoration.dump new file mode 100644 index 0000000000..31eb6574cd --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_bottom_position_without_decoration.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +@75 +@75 +@75 +@75 +@75 +@1|═+0#0000001#ffd7ff255@3| +0#0000000#ffffff0@4| +0#0000001#ffd7ff255|t|i|t|l|e| | +0#0000000#ffffff0@12| +0#0000001#ffd7ff255@3| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@1|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@4|a+0#0000001#ffd7ff255|s|d|f| @2| +0#0000000#ffffff0@2|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@5|a+0#0000001#ffd7ff255|s|d|f| +0#0000000#ffffff0@40 +@75 +> @74 +|:|c|a|l@1| |C|r|e|a|t|e|P|o|p|u|p|(|)| @37|1|9|,|0|-|1| @7|A|l@1| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index ed903bdbb3..0ee6e89108 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -4570,4 +4570,53 @@ func Test_popupwin_firstline_after_scroll() call StopVimInTerminal(buf) endfunc +func Test_popupwin_bottom_position_without_decoration() + CheckScreendump + let lines =<< trim END + function! CreatePopup() + call popup_create(repeat(['asdf'], 10), { + \ 'pos': 'topleft', + \ 'col': 'cursor+1', + \ 'line': 'cursor', + \ 'border': [1, 0, 0, 0], + \ 'padding': [0, 0, 0, 0], + \ 'title': '', + \ }) + call popup_create(repeat(['asdf'], 10), { + \ 'pos': 'topleft', + \ 'col': 'cursor+10', + \ 'line': 'cursor', + \ 'border': [0, 0, 0, 0], + \ 'padding': [0, 0, 0, 0], + \ 'title': 'title', + \ }) + call popup_create(repeat(['asdf'], 10), { + \ 'pos': 'topleft', + \ 'col': 'cursor+20', + \ 'line': 'cursor', + \ 'border': [0, 0, 0, 0], + \ 'padding': [0, 0, 0, 0], + \ 'title': '', + \ }) + call popup_create(repeat(['asdf'], 10), { + \ 'pos': 'topleft', + \ 'col': 'cursor+30', + \ 'line': 'cursor', + \ 'border': [0, 0, 0, 0], + \ 'padding': [1, 0, 0, 0], + \ 'title': '', + \ }) + endfunction + END + call writefile(lines, 'XtestPopupBottomPostion', 'D') + let buf = RunVimInTerminal('-S XtestPopupBottomPostion', #{rows: 20}) + call term_sendkeys(buf, 'a') + call term_sendkeys(buf, repeat("\", 18)) + call TermWait(buf, 50) + call term_sendkeys(buf, "\:call CreatePopup()\") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_popupwin_bottom_position_without_decoration', {}) + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 diff --git a/src/version.c b/src/version.c index b0cc80277c..8553229633 100644 --- a/src/version.c +++ b/src/version.c @@ -724,6 +724,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1660, /**/ 1659, /**/