patch 9.2.0530: WinBar row vertical separator not refreshed on window change
Commit:
https://github.com/vim/vim/commit/24678d31c88c1b6e1a2880e8ee29a44c192cb3c3
Author: Hirohito Higashi <
h.eas...@gmail.com>
Date: Sun May 24 17:43:32 2026 +0000
patch 9.2.0530: WinBar row vertical separator not refreshed on window change
Problem: After the current window changes, the vertical separator cell
on the WinBar row keeps its previous VertSplit / VertSplitNC
highlight. Content rows and status line rows of the same
window are refreshed correctly; only the WinBar row is left
behind, so the WinBar's separator no longer matches the
surrounding cells (Mao-Yining)
Solution: Include the WinBar row in draw_vsep_win() when redrawing
from the top of the window. When called with row == 0 the
loop now starts at wp->w_winrow (the WinBar row when present)
instead of W_WINROW(wp) (the content start), so the separator
highlight on the WinBar row is updated together with the rest
of the window (Hirohito Higashi).
fixes: #20304
closes: #20310
Co-Authored-By: Claude Opus 4.7 (1M context) <
nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <
h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/screen.c b/src/screen.c
index 8c1b8da0a..9042d90de 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1222,8 +1222,11 @@ draw_vsep_win(win_T *wp, int row)
int content_end = W_WINROW(wp) + wp->w_height;
- // Content rows: VertSplit/VertSplitNC based on adjacency.
- for (int r = W_WINROW(wp) + row; r < content_end; ++r)
+ // Content rows: VertSplit/VertSplitNC based on adjacency. Include the
+ // WinBar row (above the content) when redrawing from the top so that
+ // the separator highlight is updated on current-window changes.
+ int start_row = (row == 0) ? wp->w_winrow : W_WINROW(wp) + row;
+ for (int r = start_row; r < content_end; ++r)
{
int hl;
int c = fillchar_vsep(&hl, wp, r);
diff --git a/src/testdir/dumps/Test_winbar_vsep_active.dump b/src/testdir/dumps/Test_winbar_vsep_active.dump
new file mode 100644
index 000000000..9a0e23404
--- /dev/null
+++ b/src/testdir/dumps/Test_winbar_vsep_active.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@19||+0#000000255&| +0#0000000&@18||+0#000000255&| +0#0000000&@18
+|~+0#4040ff13&| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|<+1#0000000&|N|o| |N|a|m|e|]| |0|,|0|-|1| @1|A|l@1| |<|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1| |<|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1
+| +0&#e0e0e08| +2#ffffff16#6c6c6c255|S|t|e|p| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|N|e|x|t| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|F|i|n|i|s|h| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|C|o||+1#87afff255#ffffff0| +0#0000000&@28
+> @29||+1#87afff255&|~+0#4040ff13&| @27
+|~| @28||+1#87afff255&|~+0#4040ff13&| @27
+|~| @28||+1#87afff255&|~+0#4040ff13&| @27
+|~| @28||+1#87afff255&|~+0#4040ff13&| @27
+|~| @28||+1#87afff255&|~+0#4040ff13&| @27
+|~| @28||+1#87afff255&|~+0#4040ff13&| @27
+|~| @28||+1#87afff255&|~+0#4040ff13&| @27
+|[+3#0000000&|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @6|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @5|A|l@1
+| +0&&@59
diff --git a/src/testdir/dumps/Test_winbar_vsep_inactive.dump b/src/testdir/dumps/Test_winbar_vsep_inactive.dump
new file mode 100644
index 000000000..2e6f17fe7
--- /dev/null
+++ b/src/testdir/dumps/Test_winbar_vsep_inactive.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@19||+1#87afff255&| +0#0000000&@18||+0#000000255&| +0#0000000&@18
+|~+0#4040ff13&| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17
+|<+3#0000000&|N|o| |N|a|m|e|]| |0|,|0|-|1| @1|A|l@1| |<+1&&|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1| |<|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1
+| +0&#e0e0e08| +2#ffffff16#6c6c6c255|S|t|e|p| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|N|e|x|t| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|F|i|n|i|s|h| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|C|o||+0#000000255#ffffff0| +0#0000000&@28
+@30||+0#000000255&|~+0#4040ff13&| @27
+|~| @28||+0#000000255&|~+0#4040ff13&| @27
+|~| @28||+0#000000255&|~+0#4040ff13&| @27
+|~| @28||+0#000000255&|~+0#4040ff13&| @27
+|~| @28||+0#000000255&|~+0#4040ff13&| @27
+|~| @28||+0#000000255&|~+0#4040ff13&| @27
+|~| @28||+0#000000255&|~+0#4040ff13&| @27
+|[+1#0000000&|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @6|A|l@1| |[|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @5|A|l@1
+| +0&&@59
diff --git a/src/testdir/test_winbar.vim b/src/testdir/test_winbar.vim
index 59241746b..3a9ca68e8 100644
--- a/src/testdir/test_winbar.vim
+++ b/src/testdir/test_winbar.vim
@@ -157,6 +157,36 @@ func Test_winbar_not_visible_custom_statusline()
call StopVimInTerminal(buf)
endfunction
+" The vertical separator on the WinBar row must follow VertSplit/VertSplitNC
+" when the current window changes.
+func Test_winbar_vsep_highlight_after_focus_change()
+ CheckScreendump
+
+ let lines =<< trim END
+ vim9script
+ wincmd s
+ wincmd v
+ wincmd v
+ wincmd j
+ wincmd v
+ nnoremenu 1.10 WinBar.Step :Step<CR>
+ nnoremenu 1.20 WinBar.Next :Next<CR>
+ nnoremenu 1.30 WinBar.Finish :Finish<CR>
+ nnoremenu 1.40 WinBar.Cont :Continue<CR>
+ hi Vertsplit term=reverse ctermfg=111
+ hi VertsplitNC term=reverse ctermfg=16
+ END
+ call writefile(lines, 'XtestWinbarVsep', 'D')
+ let buf = RunVimInTerminal('-S XtestWinbarVsep', #{rows: 20, cols: 60})
+
+ call VerifyScreenDump(buf, 'Test_winbar_vsep_active', {})
+
+ call term_sendkeys(buf, "\<C-W>k")
+ call VerifyScreenDump(buf, 'Test_winbar_vsep_inactive', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_drag_statusline_with_winbar()
call SetupWinbar()
let save_mouse = &mouse
diff --git a/src/version.c b/src/version.c
index ca5b3ec12..ca41d42a5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 530,
/**/
529,
/**/