mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
fix(window): don't enter unfocusable or hidden prevwin (#34486)
Problem: When closing a floating window, the next window to be entered may be unfocusable or hidden. Solution: Don't enter prevwin when it is unfocusable or hidden. Enter firstwin instead (like for when prevwin is no longer valid).
This commit is contained in:
@ -2753,15 +2753,7 @@ int win_close(win_T *win, bool free_buf, bool force)
|
||||
|
||||
// Guess which window is going to be the new current window.
|
||||
// This may change because of the autocommands (sigh).
|
||||
if (!win->w_floating) {
|
||||
wp = frame2win(win_altframe(win, NULL));
|
||||
} else {
|
||||
if (win_valid(prevwin) && prevwin != win) {
|
||||
wp = prevwin;
|
||||
} else {
|
||||
wp = firstwin;
|
||||
}
|
||||
}
|
||||
wp = win->w_floating ? win_float_find_altwin(win, NULL) : frame2win(win_altframe(win, NULL));
|
||||
|
||||
// Be careful: If autocommands delete the window or cause this window
|
||||
// to be the last one left, return now.
|
||||
|
@ -362,13 +362,15 @@ win_T *win_float_find_preview(void)
|
||||
win_T *win_float_find_altwin(const win_T *win, const tabpage_T *tp)
|
||||
FUNC_ATTR_NONNULL_ARG(1)
|
||||
{
|
||||
win_T *wp = prevwin;
|
||||
if (tp == NULL) {
|
||||
return (win_valid(prevwin) && prevwin != win) ? prevwin : firstwin;
|
||||
return (win_valid(wp) && wp != win && wp->w_config.focusable
|
||||
&& !wp->w_config.hide) ? wp : firstwin;
|
||||
}
|
||||
|
||||
assert(tp != curtab);
|
||||
return (tabpage_win_valid(tp, tp->tp_prevwin) && tp->tp_prevwin != win) ? tp->tp_prevwin
|
||||
: tp->tp_firstwin;
|
||||
wp = tabpage_win_valid(tp, tp->tp_prevwin) ? tp->tp_prevwin : tp->tp_firstwin;
|
||||
return (wp->w_config.focusable && !wp->w_config.hide) ? wp : tp->tp_firstwin;
|
||||
}
|
||||
|
||||
/// Inline helper function for handling errors and cleanup in win_float_create.
|
||||
|
@ -730,6 +730,32 @@ describe('API/win', function()
|
||||
eq(prevwin, api.nvim_tabpage_get_win(tab))
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('closing a float does not enter unfocusable or hidden prevwin', function()
|
||||
local firstwin = api.nvim_get_current_win()
|
||||
local wins = {} ---@type integer[]
|
||||
for _ = 1, 4 do
|
||||
wins[#wins + 1] = api.nvim_open_win(0, true, {
|
||||
relative = 'editor',
|
||||
row = 10,
|
||||
col = 10,
|
||||
width = 50,
|
||||
height = 10,
|
||||
})
|
||||
end
|
||||
api.nvim_win_set_config(wins[3], { hide = true })
|
||||
api.nvim_win_close(0, false)
|
||||
eq(firstwin, api.nvim_get_current_win())
|
||||
api.nvim_set_current_win(wins[2])
|
||||
api.nvim_set_current_win(wins[3])
|
||||
api.nvim_win_set_config(wins[2], { focusable = false })
|
||||
api.nvim_win_close(0, false)
|
||||
eq(firstwin, api.nvim_get_current_win())
|
||||
api.nvim_set_current_win(wins[1])
|
||||
api.nvim_set_current_win(wins[2])
|
||||
api.nvim_win_close(0, false)
|
||||
eq(wins[1], api.nvim_get_current_win())
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('hide', function()
|
||||
|
Reference in New Issue
Block a user