diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-10-22 07:53:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-22 07:53:39 +0800 |
commit | 2f9b94a26836ecb081c717e23913f5b6576cce99 (patch) | |
tree | 6daddda09d6fe929785c840a054099643bcf4165 | |
parent | 90138d5ed87cc8dde49ee74e422a5de2191a3f76 (diff) | |
download | rneovim-2f9b94a26836ecb081c717e23913f5b6576cce99.tar.gz rneovim-2f9b94a26836ecb081c717e23913f5b6576cce99.tar.bz2 rneovim-2f9b94a26836ecb081c717e23913f5b6576cce99.zip |
fix(ui): send grid_resize events before triggering VimResized (#20760)
-rw-r--r-- | src/nvim/drawscreen.c | 52 | ||||
-rw-r--r-- | test/functional/ui/screen_basic_spec.lua | 25 |
2 files changed, 46 insertions, 31 deletions
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index a1582eac53..adf52ef6e4 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -125,6 +125,8 @@ void conceal_check_cursor_line(void) /// default_grid.Columns to access items in default_grid.chars[]. Use Rows /// and Columns for positioning text etc. where the final size of the screen is /// needed. +/// +/// @return whether resizing has been done bool default_grid_alloc(void) { static bool resizing = false; @@ -264,17 +266,28 @@ void screen_resize(int width, int height) p_lines = Rows; p_columns = Columns; - // was invoked recursively from a VimResized autocmd, handled as a loop below - if (resizing_autocmd) { - return; - } + ui_call_grid_resize(1, width, height); int retry_count = 0; resizing_autocmd = true; - bool retry_resize = true; - while (retry_resize) { - retry_resize = default_grid_alloc(); + // In rare cases, autocommands may have altered Rows or Columns, + // so retry to check if we need to allocate the screen again. + while (default_grid_alloc()) { + // win_new_screensize will recompute floats position, but tell the + // compositor to not redraw them yet + ui_comp_set_screen_valid(false); + if (msg_grid.chars) { + msg_grid_invalid = true; + } + + RedrawingDisabled++; + + win_new_screensize(); // fit the windows in the new sized screen + + comp_col(); // recompute columns for shown command and ruler + + RedrawingDisabled--; // Do not apply autocommands more than 3 times to avoid an endless loop // in case applying autocommands always changes Rows or Columns. @@ -282,33 +295,10 @@ void screen_resize(int width, int height) break; } - if (retry_resize) { - // In rare cases, autocommands may have altered Rows or Columns, - // retry to check if we need to allocate the screen again. - apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, false, curbuf); - } + apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, false, curbuf); } resizing_autocmd = false; - - ui_call_grid_resize(1, width, height); - - // win_new_screensize will recompute floats position, but tell the - // compositor to not redraw them yet - ui_comp_set_screen_valid(false); - if (msg_grid.chars) { - msg_grid_invalid = true; - } - - // Note that the window sizes are updated before reallocating the arrays, - // thus we must not redraw here! - RedrawingDisabled++; - - win_new_screensize(); // fit the windows in the new sized screen - - comp_col(); // recompute columns for shown command and ruler - - RedrawingDisabled--; redraw_all_later(UPD_CLEAR); if (starting != NO_SCREEN) { diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index f111aa2513..5aacdc95e2 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -894,6 +894,31 @@ local function screen_tests(linegrid) :ls^ | ]]) end) + + it('VimResized autocommand does not cause invalid UI events #20692 #20759', function() + feed('<Esc>') + command([[autocmd VimResized * redrawtabline]]) + command([[autocmd VimResized * lua vim.api.nvim_echo({ { 'Hello' } }, false, {})]]) + command([[autocmd VimResized * let g:echospace = v:echospace]]) + meths.set_option('showtabline', 2) + screen:expect([[ + {2: + [No Name] }{3: }| + resiz^e | + {0:~ }| + {0:~ }| + | + ]]) + screen:try_resize(30, 6) + screen:expect([[ + {2: + [No Name] }{3: }| + resiz^e | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + eq(29, meths.get_var('echospace')) + end) end) describe('press enter', function() |