screen: disable redrawing inside VimResized

Note: test doesn't fail on master. I cannot reproduce the glitches with
-u NONE, probably it requires interfering events. But add some coverage
for these checks at least.
This commit is contained in:
Björn Linse 2019-06-26 19:42:57 +02:00
parent 0d82aaf586
commit 51a451570d
2 changed files with 61 additions and 13 deletions

View File

@ -153,6 +153,8 @@ static bool conceal_cursor_used = false;
static bool redraw_popupmenu = false;
static bool resizing = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
#endif
@ -275,7 +277,9 @@ int update_screen(int type)
int did_one;
// Don't do anything if the screen structures are (not yet) valid.
if (!default_grid.chars) {
// A VimResized autocmd can invoke redrawing in the middle of a resize,
// which would bypass the checks in screen_resize for popupmenu etc.
if (!default_grid.chars || resizing) {
return FAIL;
}
@ -5989,7 +5993,14 @@ void grid_assign_handle(ScreenGrid *grid)
/// needed.
void screenalloc(void)
{
static bool entered = false; // avoid recursiveness
// It's possible that we produce an out-of-memory message below, which
// will cause this function to be called again. To break the loop, just
// return here.
if (resizing) {
return;
}
resizing = true;
int retry_count = 0;
retry:
@ -6003,18 +6014,10 @@ retry:
|| Rows == 0
|| Columns == 0
|| (!full_screen && default_grid.chars == NULL)) {
resizing = false;
return;
}
/*
* It's possible that we produce an out-of-memory message below, which
* will cause this function to be called again. To break the loop, just
* return here.
*/
if (entered)
return;
entered = TRUE;
/*
* Note that the window sizes are updated before reallocating the arrays,
* thus we must not redraw here!
@ -6055,8 +6058,7 @@ retry:
must_redraw = CLEAR; // need to clear the screen later
entered = FALSE;
--RedrawingDisabled;
RedrawingDisabled--;
/*
* Do not apply autocommands more than 3 times to avoid an endless loop
@ -6068,6 +6070,8 @@ retry:
* jump back to check if we need to allocate the screen again. */
goto retry;
}
resizing = false;
}
void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy, bool valid)

View File

@ -1152,6 +1152,50 @@ describe('builtin popupmenu', function()
]])
end)
it('behaves correcty with VimResized autocmd', function()
feed('isome long prefix before the ')
command("set completeopt+=noinsert,noselect")
command("autocmd VimResized * redraw!")
command("set linebreak")
funcs.complete(29, {'word', 'choice', 'text', 'thing'})
screen:expect([[
some long prefix before the ^ |
{1:~ }{n: word }|
{1:~ }{n: choice}|
{1:~ }{n: text }|
{1:~ }{n: thing }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{2:-- INSERT --} |
]])
screen:try_resize(16,10)
screen:expect([[
some long |
prefix before |
the ^ |
{1:~ }{n: word }|
{1:~ }{n: choice }|
{1:~ }{n: text }|
{1:~ }{n: thing }|
{1:~ }|
{1:~ }|
{2:-- INSERT --} |
]])
end)
it('works with rightleft window', function()
command("set rl")
feed('isome rightleft ')