aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-10-22 07:53:39 +0800
committerGitHub <noreply@github.com>2022-10-22 07:53:39 +0800
commit2f9b94a26836ecb081c717e23913f5b6576cce99 (patch)
tree6daddda09d6fe929785c840a054099643bcf4165
parent90138d5ed87cc8dde49ee74e422a5de2191a3f76 (diff)
downloadrneovim-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.c52
-rw-r--r--test/functional/ui/screen_basic_spec.lua25
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()