From 1741da8412134fc5a2f83e509da925c4e2d65034 Mon Sep 17 00:00:00 2001 From: Sean Dewar <6256228+seandewar@users.noreply.github.com> Date: Thu, 16 Jul 2026 00:09:54 +0100 Subject: [PATCH] fix(window): yeet grid later when closing float in other tabpage #40758 Problem: #40731 may still crash if close_buffer autocmds reinsert the float's grid. Plus removing the grid (and posting win_close) is unneeded if win_close_othertab refuses to close the window later, which is possible. Solution: do the stuff before freeing the window, like win_close. --- src/nvim/window.c | 14 +++++++------- test/functional/ui/float_spec.lua | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/nvim/window.c b/src/nvim/window.c index 1db79abd40..d110329ddf 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3215,13 +3215,6 @@ bool win_close_othertab(win_T *win, int free_buf, tabpage_T *tp, bool force) } } - if (ui_has(kUIMultigrid)) { - ui_call_win_close(win->w_grid_alloc.handle); - } - if (win->w_floating) { - ui_comp_remove_grid(&win->w_grid_alloc); - } - bufref_T bufref; set_bufref(&bufref, win->w_buffer); @@ -3274,6 +3267,13 @@ bool win_close_othertab(win_T *win, int free_buf, tabpage_T *tp, bool force) } } + if (ui_has(kUIMultigrid)) { + ui_call_win_close(win->w_grid_alloc.handle); + } + if (win->w_floating) { + ui_comp_remove_grid(&win->w_grid_alloc); + } + // About to free the window. Remember its final buffer for terminal_check_size/TabClosed, // which may have changed since the last set_bufref. (e.g: close_buffer autocmds) set_bufref(&bufref, win->w_buffer); diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 436ad5bee0..f42dd9b593 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -10526,12 +10526,22 @@ describe('float window', function() it('no crash when closing a floating window from a non-current tab', function() local buf = api.nvim_create_buf(false, true) local win = api.nvim_open_win(buf, false, { relative = 'editor', width = 5, height = 5, row = 0, col = 0 }) - exec_lua(function() + local triggered = exec_lua(function() vim.cmd.tabnew() vim.api.nvim_win_call(win, vim.cmd.redraw) + local triggered = false + vim.api.nvim_create_autocmd('BufHidden', { + once = true, + buf = buf, + callback = function() + vim.api.nvim_win_call(win, vim.cmd.redraw) + triggered = true + end, + }) + vim.api.nvim_win_close(win, true) + return triggered end) - api.nvim_win_close(win, true) - assert_alive() + eq(true, triggered) end) it(':sleep cursor placement #22639', function()