fix(kitty): restore per-host tab colors in the custom tab bar

a68b138 made draw_tab() derive all four color roles from tab_colors(),
so it stopped reading the per-tab colors that `kitten @ set-tab-color`
sets. The ssh wrapper (__kitty_tab_set) still set them, but the renderer
discarded them and every remote tab drew in the #2e84e6 accent.

Resolve the drawn colors through DrawData.tab_fg/tab_bg on the already
role-substituted title_draw_data: those return the per-tab override when
one is set and the accent roles otherwise. Theme-provided tab colors
still cannot leak in, so the theme-independence fix is preserved.

Extend tests/test_tab_bar_colors.py with the override case; it fails
against the old renderer (got the accent, wanted the host color).
This commit is contained in:
Anton Volnuhin 2026-08-06 01:31:40 +03:00
parent 739e906080
commit 31d3048abe
2 changed files with 36 additions and 6 deletions

View File

@ -87,7 +87,37 @@ for theme_bg in (0xF8F8F8, 0x1C2836):
f"got {(actual_fg, actual_bg)!r}" f"got {(actual_fg, actual_bg)!r}"
) )
# Per-tab colors set by `kitten @ set-tab-color` (see fish __kitty_tab_set)
# must win over the accent, or ssh tabs all render in the same blue.
HOST_BG = 0x689D6A
HOST_FG = 0x000000
for theme_bg in (0xF8F8F8, 0x1C2836):
for tab, expected, label in (
(
TabBarData("tab", is_active=True, active_bg=HOST_BG, active_fg=HOST_FG),
(as_rgb(HOST_FG), as_rgb(HOST_BG)),
"active tab takes the host color",
),
(
TabBarData("tab", is_active=False, inactive_fg=HOST_BG),
(as_rgb(HOST_BG), as_rgb(theme_bg)),
"inactive tab keeps the theme background, host color as text",
),
):
screen = RecordingScreen()
renderer.draw_tab(
draw_data(theme_bg), screen, tab, 0, 1, 1, True, ExtraData()
)
_, actual_fg, actual_bg = screen.draws[0]
if (actual_fg, actual_bg) != expected:
raise RuntimeError(
f"theme #{theme_bg:06x}, {label}: "
f"expected cursor colors {expected!r}, "
f"got {(actual_fg, actual_bg)!r}"
)
print( print(
"PASS: tab colors ignore theme-provided tab roles " "PASS: tab colors ignore theme-provided tab roles "
"for light and dark backgrounds" "for light and dark backgrounds, and honor per-tab set-tab-color overrides"
) )

View File

@ -24,12 +24,12 @@ def draw_tab(
extra_data: ExtraData extra_data: ExtraData
) -> int: ) -> int:
colors = tab_colors(draw_data.default_bg) colors = tab_colors(draw_data.default_bg)
fg = colors.active_fg if tab.is_active else colors.inactive_fg
bg = colors.active_bg if tab.is_active else colors.inactive_bg
default_bg = as_rgb(int(draw_data.default_bg))
orig_fg = as_rgb(int(fg))
orig_bg = as_rgb(int(bg))
title_draw_data = draw_data._replace(**colors._asdict()) title_draw_data = draw_data._replace(**colors._asdict())
default_bg = as_rgb(int(draw_data.default_bg))
# tab_fg/tab_bg return a per-tab color when `kitten @ set-tab-color` has set
# one (the ssh wrapper tints tabs per host), else the roles above.
orig_fg = as_rgb(title_draw_data.tab_fg(tab))
orig_bg = as_rgb(title_draw_data.tab_bg(tab))
screen.cursor.fg = orig_fg screen.cursor.fg = orig_fg
screen.cursor.bg = orig_bg screen.cursor.bg = orig_bg
left_sep, right_sep = ('', '') left_sep, right_sep = ('', '')