# HG changeset patch # User Bram Moolenaar # Date 1637181905 -3600 # Node ID 7b07f361b1d45ecf15587a937a3e6a30cf0cfa9c # Parent 54e3f0441e896ab0fc5ce8b3fc87001dd41d23e5 patch 8.2.3614: zindex of popup windows not used when redrawing popup menu Commit: https://github.com/vim/vim/commit/6555500bcf280716187eea9dba22d4f69bc0a501 Author: Bakudankun Date: Wed Nov 17 20:40:16 2021 +0000 patch 8.2.3614: zindex of popup windows not used when redrawing popup menu Problem: zindex of popup windows not used when redrawing popup menu. Solution: Check the zindex when redrawing the popup menu. (closes https://github.com/vim/vim/issues/9129, closes #9089) diff --git a/src/popupmenu.c b/src/popupmenu.c --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -382,9 +382,9 @@ pum_call_update_screen() * "row"/"col" is under the popup menu. */ int -pum_under_menu(int row, int col) +pum_under_menu(int row, int col, int only_redrawing) { - return pum_will_redraw + return (!only_redrawing || pum_will_redraw) && row >= pum_row && row < pum_row + pum_height && col >= pum_col - 1 diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -3654,7 +3654,11 @@ may_update_popup_mask(int type) for (col = wp->w_wincol; col < wp->w_wincol + width - wp->w_popup_leftoff && col < screen_Columns; ++col) - if (wp->w_popup_mask_cells == NULL + if (wp->w_zindex < POPUPMENU_ZINDEX + && pum_visible() + && pum_under_menu(line, col, FALSE)) + mask[line * screen_Columns + col] = POPUPMENU_ZINDEX; + else if (wp->w_popup_mask_cells == NULL || !popup_masked(wp, width, height, col, line)) mask[line * screen_Columns + col] = wp->w_zindex; } diff --git a/src/proto/popupmenu.pro b/src/proto/popupmenu.pro --- a/src/proto/popupmenu.pro +++ b/src/proto/popupmenu.pro @@ -1,7 +1,7 @@ /* popupmenu.c */ void pum_display(pumitem_T *array, int size, int selected); void pum_call_update_screen(void); -int pum_under_menu(int row, int col); +int pum_under_menu(int row, int col, int only_redrawing); void pum_redraw(void); void pum_position_info_popup(win_T *wp); void pum_undisplay(void); diff --git a/src/screen.c b/src/screen.c --- a/src/screen.c +++ b/src/screen.c @@ -2139,7 +2139,7 @@ screen_char(unsigned off, int row, int c // Skip if under the popup menu. // Popup windows with zindex higher than POPUPMENU_ZINDEX go on top. - if (pum_under_menu(row, col) + if (pum_under_menu(row, col, TRUE) #ifdef FEAT_PROP_POPUP && screen_zindex <= POPUPMENU_ZINDEX #endif diff --git a/src/testdir/dumps/Test_popupwin_popupmenu_masking_1.dump b/src/testdir/dumps/Test_popupwin_popupmenu_masking_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_popupmenu_masking_1.dump @@ -0,0 +1,14 @@ +|t+0&#ffffff0|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|a|w|o|r|d> @2|p+0#ffffff16#e000002|o|p|u|p| |b|e|l|o|w| @1|╔+0#0000001#e0e0e08|═@15|X| +0#0000000#ffffff0@9 +|~+0#4040ff13&| @23| +0#0000001#e0e0e08|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| |║| |w|o|r|d|s| |a|r|e| |c|o@1|l| |║| +0#4040ff13#ffffff0@9 +|~| @23| +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| |╚+0&#e0e0e08|═@15|⇲| +0#4040ff13#ffffff0@9 +|~| @19|p+0#0000000#ffff4012|o|p|u|p| |o|n| |t|o|p| +0#0000001#ffd7ff255|W| |e|x|t|r|a| |t|e|x|t| | +0#ffffff16#e000002@3| +0#4040ff13#ffffff0@23 +|~| @19|p+0#0000000#ffff4012|o|p|u|p| |o|n| |t|o|p| +0#0000001#ffd7ff255|W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27 +|~| @19|p+0#0000000#ffff4012|o|p|u|p| |o|n| |t|o|p| +0#4040ff13#ffffff0@41 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_popupwin_popupmenu_masking_2.dump b/src/testdir/dumps/Test_popupwin_popupmenu_masking_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_popupmenu_masking_2.dump @@ -0,0 +1,14 @@ +|t+0&#ffffff0|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|a|w|o|r>d| @2|p+0#ffffff16#e000002|o|p|u|p| |b|e|l|o|w| @5| +0#0000000#ffffff0@23 +|~+0#4040ff13&| @32|p+0#ffffff16#e000002|o|p|u|p| |b|e|l|o|w| @5| +0#4040ff13#ffffff0@23 +|~| @32|p+0#ffffff16#e000002|o|p|u|p| |b|e|l|o|w| @5| +0#4040ff13#ffffff0@23 +|~| @19|p+0#0000000#ffff4012|o|p|u|p| |o|n| |t|o|p| +0#4040ff13#ffffff0|p+0#ffffff16#e000002|o|p|u|p| |b|e|l|o|w| @5| +0#4040ff13#ffffff0@23 +|~| @19|p+0#0000000#ffff4012|o|p|u|p| |o|n| |t|o|p| +0#4040ff13#ffffff0@41 +|~| @19|p+0#0000000#ffff4012|o|p|u|p| |o|n| |t|o|p| +0#4040ff13#ffffff0@41 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|1|,|3|1| @9|A|l@1| 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 @@ -3328,6 +3328,32 @@ func Get_popupmenu_lines() endif endfunc + func OpenOtherPopups() + call popup_create([ + \ 'popup below', + \ 'popup below', + \ 'popup below', + \ 'popup below', + \ ], #{ + \ line: 'cursor', + \ col: 'cursor+3', + \ highlight: 'ErrorMsg', + \ minwidth: 17, + \ zindex: 50, + \ }) + call popup_create([ + \ 'popup on top', + \ 'popup on top', + \ 'popup on top', + \ ], #{ + \ line: 'cursor+3', + \ col: 'cursor-10', + \ highlight: 'Search', + \ minwidth: 10, + \ zindex: 200, + \ }) + endfunc + " Check that no autocommands are triggered for the info popup au WinEnter * if win_gettype() == 'popup' | call setline(2, 'WinEnter') | endif au WinLeave * if win_gettype() == 'popup' | call setline(2, 'WinLeave') | endif @@ -3520,6 +3546,29 @@ func Test_popupmenu_info_too_wide() call delete('XtestInfoPopupWide') endfunc +func Test_popupmenu_masking() + " Test that popup windows that are opened while popup menu is open are + " properly displayed. + CheckScreendump + CheckFeature quickfix + + let lines = Get_popupmenu_lines() + call add(lines, 'inoremap call OpenOtherPopups()') + call writefile(lines, 'XtestPopupmenuMasking') + + let buf = RunVimInTerminal('-S XtestPopupmenuMasking', #{rows: 14}) + call TermWait(buf, 25) + + call term_sendkeys(buf, "A\\\") + call VerifyScreenDump(buf, 'Test_popupwin_popupmenu_masking_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_popupwin_popupmenu_masking_2', {}) + + call StopVimInTerminal(buf) + call delete('XtestPopupmenuMasking') +endfunc + func Test_popupwin_recycle_bnr() let bufnr = popup_notification('nothing wrong', {})->winbufnr() call popup_clear() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3614, +/**/ 3613, /**/ 3612,