%bwipe!
endfunc
+" This used to trigger WinClosed twice for the same window, and the window's
+" buffer was NULL in the second autocommand.
+func Test_WinClosed_BufUnload_close_other()
+ tabnew
+ let g:tab = tabpagenr()
+ let g:buf = bufnr()
+ new
+ setlocal bufhidden=wipe
+ augroup test-WinClosed
+ autocmd BufUnload * ++once exe g:buf .. 'bwipe!'
+ autocmd WinClosed * call tabpagebuflist(g:tab)
+ augroup END
+ close
+
+ unlet g:tab
+ unlet g:buf
+ autocmd! test-WinClosed
+ augroup! test-WinClosed
+ %bwipe!
+endfunc
+
func s:AddAnAutocmd()
augroup vimBarTest
au BufReadCmd * echo 'hello'
/*
* Close the possibly last window in a tab page.
- * Returns TRUE when the window was closed already.
+ * Return FALSE if there are other windows and nothing is done, TRUE otherwise.
*/
static int
close_last_window_tabpage(
// and then close the window and the tab page to avoid that curwin and
// curtab are invalid while we are freeing memory.
if (close_last_window_tabpage(win, free_buf, prev_curtab))
- return FAIL;
+ return FAIL;
// When closing the help window, try restoring a snapshot after closing
// the window. Otherwise clear the snapshot, it's now invalid.
win_close_buffer(win, free_buf ? DOBUF_UNLOAD : 0, TRUE);
- if (only_one_window() && win_valid(win) && win->w_buffer == NULL
- && (last_window() || curtab != prev_curtab
- || close_last_window_tabpage(win, free_buf, prev_curtab)))
+ if (win_valid(win) && win->w_buffer == NULL
+#if defined(FEAT_PROP_POPUP)
+ && !popup_is_popup(win)
+#endif
+ && last_window())
{
// Autocommands have closed all windows, quit now. Restore
// curwin->w_buffer, otherwise writing viminfo may fail.
&& win->w_buffer == NULL)
{
// Need to close the window anyway, since the buffer is NULL.
- // Don't trigger autocmds with a NULL buffer.
- block_autocmds();
win_close_othertab(win, FALSE, prev_curtab);
- unblock_autocmds();
return FAIL;
}
return; // window is already being closed
// Trigger WinClosed just before starting to free window-related resources.
- trigger_winclosed(win);
- // autocmd may have freed the window already.
- if (!win_valid_any_tab(win))
- return;
+ // If the buffer is NULL, it isn't safe to trigger autocommands,
+ // and win_close() should have already triggered WinClosed.
+ if (win->w_buffer != NULL)
+ {
+ trigger_winclosed(win);
+ // autocmd may have freed the window already.
+ if (!win_valid_any_tab(win))
+ return;
+ }
if (win->w_buffer != NULL)
// Close the link to the buffer.