diff --git a/src/nvim/window.c b/src/nvim/window.c index 8acafa4e76..42bf558799 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -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. diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 2e6927a23b..c0ec36c30c 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -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. diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 75058d259c..1b64fada5a 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -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()