mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +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).
(cherry picked from commit 0d658660c2)
			
			
This commit is contained in:
		
				
					committed by
					
						
						github-actions[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							a34b8e42df
						
					
				
				
					commit
					742ea00742
				
			@@ -2741,15 +2741,7 @@ int win_close(win_T *win, bool free_buf, bool force)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Guess which window is going to be the new current window.
 | 
					    // Guess which window is going to be the new current window.
 | 
				
			||||||
    // This may change because of the autocommands (sigh).
 | 
					    // This may change because of the autocommands (sigh).
 | 
				
			||||||
    if (!win->w_floating) {
 | 
					    wp = win->w_floating ? win_float_find_altwin(win, NULL) : frame2win(win_altframe(win, NULL));
 | 
				
			||||||
      wp = frame2win(win_altframe(win, NULL));
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      if (win_valid(prevwin) && prevwin != win) {
 | 
					 | 
				
			||||||
        wp = prevwin;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        wp = firstwin;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Be careful: If autocommands delete the window or cause this window
 | 
					    // Be careful: If autocommands delete the window or cause this window
 | 
				
			||||||
    // to be the last one left, return now.
 | 
					    // to be the last one left, return now.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -367,13 +367,15 @@ win_T *win_float_find_preview(void)
 | 
				
			|||||||
win_T *win_float_find_altwin(const win_T *win, const tabpage_T *tp)
 | 
					win_T *win_float_find_altwin(const win_T *win, const tabpage_T *tp)
 | 
				
			||||||
  FUNC_ATTR_NONNULL_ARG(1)
 | 
					  FUNC_ATTR_NONNULL_ARG(1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  win_T *wp = prevwin;
 | 
				
			||||||
  if (tp == NULL) {
 | 
					  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);
 | 
					  assert(tp != curtab);
 | 
				
			||||||
  return (tabpage_win_valid(tp, tp->tp_prevwin) && tp->tp_prevwin != win) ? tp->tp_prevwin
 | 
					  wp = tabpage_win_valid(tp, tp->tp_prevwin) ? tp->tp_prevwin : tp->tp_firstwin;
 | 
				
			||||||
                                                                          : 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.
 | 
					/// Inline helper function for handling errors and cleanup in win_float_create.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -745,6 +745,32 @@ describe('API/win', function()
 | 
				
			|||||||
      eq(prevwin, api.nvim_tabpage_get_win(tab))
 | 
					      eq(prevwin, api.nvim_tabpage_get_win(tab))
 | 
				
			||||||
      assert_alive()
 | 
					      assert_alive()
 | 
				
			||||||
    end)
 | 
					    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)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('hide', function()
 | 
					  describe('hide', function()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user