mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-03 17:24:29 +00:00 
			
		
		
		
	fix(window): skip unfocusable and hidden floats with "{count}<C-W>w" #33810
Problem: Using `<C-W>w`, `<C-W>W` or the ":wincmd" variants with a count can
enter unfocusable or hidden floating windows. This is especially problematic
when using the new in-development extui, which creates many unfocusable floats
for various UI elements.
Solution: Skip unfocusable and hidden floating windows. Instead, skip to the
next focusable, non-hidden window in the current tabpage's window list. Reword
the documentation a bit (hopefully an improvement?)
(cherry picked from commit 403fcacfc1)
			
			
This commit is contained in:
		
				
					committed by
					
						
						github-actions[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							4e43264cd3
						
					
				
				
					commit
					9b3426691c
				
			@@ -439,18 +439,17 @@ CTRL-W l	Move cursor to Nth window right of current one.  Uses the
 | 
			
		||||
 | 
			
		||||
CTRL-W w					*CTRL-W_w* *CTRL-W_CTRL-W*
 | 
			
		||||
CTRL-W CTRL-W	Without count: move cursor to the |focusable| window
 | 
			
		||||
		below/right of the current one.  If there is no (focusable)
 | 
			
		||||
		window below or right, go to top-left window. With count: go
 | 
			
		||||
		to Nth window (windows are numbered from top-left to
 | 
			
		||||
		bottom-right).  To obtain the window number see |bufwinnr()|
 | 
			
		||||
		and |winnr()|.  When N is larger than the number of windows go
 | 
			
		||||
		to the last window.
 | 
			
		||||
		below/right of the current one.  If none, go to the top-left
 | 
			
		||||
		window.  With count: go to Nth window (numbered top-left to
 | 
			
		||||
		bottom-right), skipping unfocusable windows.  To obtain the
 | 
			
		||||
		window number see |bufwinnr()| and |winnr()|.  When N is
 | 
			
		||||
		larger than the number of windows go to the last focusable
 | 
			
		||||
		window.
 | 
			
		||||
 | 
			
		||||
						*CTRL-W_W*
 | 
			
		||||
CTRL-W W	Without count: move cursor to the |focusable| window
 | 
			
		||||
		above/left of current one.  If there is no window above or
 | 
			
		||||
		left, go to bottom-right window.  With count: go to Nth
 | 
			
		||||
		window, like with CTRL-W w.
 | 
			
		||||
		above/left of current one.  If none, go to the bottom-right
 | 
			
		||||
		window.  With count: go to Nth window, like CTRL-W w.
 | 
			
		||||
 | 
			
		||||
CTRL-W t					*CTRL-W_t* *CTRL-W_CTRL-T*
 | 
			
		||||
CTRL-W CTRL-T	Move cursor to top-left window.
 | 
			
		||||
 
 | 
			
		||||
@@ -347,12 +347,23 @@ newwindow:
 | 
			
		||||
    } else {
 | 
			
		||||
      win_T *wp;
 | 
			
		||||
      if (Prenum) {  // go to specified window
 | 
			
		||||
        win_T *last_focusable = firstwin;
 | 
			
		||||
        for (wp = firstwin; --Prenum > 0;) {
 | 
			
		||||
          if (!wp->w_floating || (!wp->w_config.hide && wp->w_config.focusable)) {
 | 
			
		||||
            last_focusable = wp;
 | 
			
		||||
          }
 | 
			
		||||
          if (wp->w_next == NULL) {
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          wp = wp->w_next;
 | 
			
		||||
        }
 | 
			
		||||
        while (wp != NULL && wp->w_floating
 | 
			
		||||
               && (wp->w_config.hide || !wp->w_config.focusable)) {
 | 
			
		||||
          wp = wp->w_next;
 | 
			
		||||
        }
 | 
			
		||||
        if (wp == NULL) {  // went past the last focusable window
 | 
			
		||||
          wp = last_focusable;
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (nchar == 'W') {  // go to previous window
 | 
			
		||||
          wp = curwin->w_prev;
 | 
			
		||||
 
 | 
			
		||||
@@ -5632,6 +5632,59 @@ describe('float window', function()
 | 
			
		||||
                                                    |
 | 
			
		||||
          ]])
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        api.nvim_open_win(
 | 
			
		||||
          0,
 | 
			
		||||
          false,
 | 
			
		||||
          { relative = "editor", width = 1, height = 1, row = 0, col = 0 }
 | 
			
		||||
        )
 | 
			
		||||
        api.nvim_open_win(
 | 
			
		||||
          0,
 | 
			
		||||
          false,
 | 
			
		||||
          { relative = "editor", width = 1, height = 1, row = 0, col = 0, focusable = false }
 | 
			
		||||
        )
 | 
			
		||||
        api.nvim_open_win(
 | 
			
		||||
          0,
 | 
			
		||||
          false,
 | 
			
		||||
          { relative = "editor", width = 1, height = 1, row = 0, col = 0, focusable = false }
 | 
			
		||||
        )
 | 
			
		||||
        api.nvim_open_win(
 | 
			
		||||
          0,
 | 
			
		||||
          false,
 | 
			
		||||
          { relative = "editor", width = 1, height = 1, row = 0, col = 0, focusable = true }
 | 
			
		||||
        )
 | 
			
		||||
        api.nvim_open_win(
 | 
			
		||||
          0,
 | 
			
		||||
          false,
 | 
			
		||||
          { relative = "editor", width = 1, height = 1, row = 0, col = 0, focusable = false }
 | 
			
		||||
        )
 | 
			
		||||
        local nr_focusable = {}
 | 
			
		||||
        for nr = 1, fn.winnr("$") do
 | 
			
		||||
          table.insert(nr_focusable, api.nvim_win_get_config(fn.win_getid(nr)).focusable)
 | 
			
		||||
        end
 | 
			
		||||
        eq({true, false, true, false, false, true, false}, nr_focusable)
 | 
			
		||||
 | 
			
		||||
        command("1wincmd w")
 | 
			
		||||
        eq(1, fn.winnr())
 | 
			
		||||
        command("2wincmd w")
 | 
			
		||||
        eq(3, fn.winnr())
 | 
			
		||||
        command("3wincmd w")
 | 
			
		||||
        eq(3, fn.winnr())
 | 
			
		||||
        command("4wincmd w")
 | 
			
		||||
        eq(6, fn.winnr())
 | 
			
		||||
        command("5wincmd w")
 | 
			
		||||
        eq(6, fn.winnr())
 | 
			
		||||
        command("6wincmd w")
 | 
			
		||||
        eq(6, fn.winnr())
 | 
			
		||||
        command("7wincmd w")
 | 
			
		||||
        eq(6, fn.winnr())
 | 
			
		||||
 | 
			
		||||
        feed("1<c-w>w")
 | 
			
		||||
        eq(1, fn.winnr())
 | 
			
		||||
        feed("2<c-w>w")
 | 
			
		||||
        eq(3, fn.winnr())
 | 
			
		||||
        feed("999<c-w>w")
 | 
			
		||||
        eq(6, fn.winnr())
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      it("W", function()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user