* [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes
@ 2026-09-04 14:59 Konstantin Khorenko
2026-09-04 14:59 ` [PATCH b4 2/2] review-tui: read native_ansi_color for the trailer overlay header Konstantin Khorenko
2026-09-15 20:32 ` [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes Konstantin Ryabitsev
0 siblings, 2 replies; 3+ messages in thread
From: Konstantin Khorenko @ 2026-09-04 14:59 UTC (permalink / raw)
To: tools; +Cc: Konstantin Khorenko
Resolving styles under an ansi theme (TEXTUAL_THEME=ansi-light/dark,
or one picked from the command palette) crashes:
MissingStyle: 'transparent' is not a valid color
Textual's ansi themes resolve $panel/$surface to the CSS keyword
"transparent" and can suffix a colour with an alpha percentage; Rich
accepts neither. Reduce both to the terminal default colour in
_to_rich_color(), which fixes every consumer of resolve_styles().
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Assisted-by: claude-sonnet-5
---
src/b4/tui/_common.py | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/b4/tui/_common.py b/src/b4/tui/_common.py
index 844d980..a378dd3 100644
--- a/src/b4/tui/_common.py
+++ b/src/b4/tui/_common.py
@@ -278,9 +278,20 @@ def matches_limit(
variable system. Rich expects ``green``, ``bright_blue``, etc.
Non-ansi values (hex codes, named CSS colours) pass through unchanged.
``ansi_default`` maps to ``default``.
+
+ Textual's ansi themes resolve ``$panel``/``$surface`` to the CSS
+ keyword ``transparent`` and can append an alpha percentage
+ (``default 50%``). Rich understands neither, and feeding one into a
+ style string raises ``MissingStyle``, so both are reduced to the
+ terminal default colour.
"""
+ parts = textual_color.rsplit(' ', 1)
+ if len(parts) == 2 and parts[1].endswith('%'):
+ textual_color = parts[0] # drop the alpha suffix
if textual_color.startswith('ansi_'):
return textual_color[5:] # strip 'ansi_' prefix
+ if textual_color == 'transparent':
+ return 'default'
return textual_color
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH b4 2/2] review-tui: read native_ansi_color for the trailer overlay header
2026-09-04 14:59 [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes Konstantin Khorenko
@ 2026-09-04 14:59 ` Konstantin Khorenko
2026-09-15 20:32 ` [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes Konstantin Ryabitsev
1 sibling, 0 replies; 3+ messages in thread
From: Konstantin Khorenko @ 2026-09-04 14:59 UTC (permalink / raw)
To: tools; +Cc: Konstantin Khorenko
The review status overlay picks its reverse-video header style off
App.ansi_color, a tri-state that stays None until the theme is
switched at runtime, so it never reflects an ansi theme set via
TEXTUAL_THEME and the header falls back to the wrong style. Read
native_ansi_color instead, with a getattr fallback for Textual
releases that predate the property.
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Assisted-by: claude-sonnet-5
---
src/b4/review_tui/_review_app.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/b4/review_tui/_review_app.py b/src/b4/review_tui/_review_app.py
index e1082e9..da60455 100644
--- a/src/b4/review_tui/_review_app.py
+++ b/src/b4/review_tui/_review_app.py
@@ -924,7 +924,7 @@ from b4.review_tui._modals import (
if has_content:
text.append('\n')
- if self.app.ansi_color:
+ if getattr(self.app, 'native_ansi_color', self.app.ansi_color):
text.append(f' {header} ', style=f'bold reverse {colour}')
else:
text.append(f' {header} ', style=f'bold {ts["surface"]} on {colour}')
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes
2026-09-04 14:59 [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes Konstantin Khorenko
2026-09-04 14:59 ` [PATCH b4 2/2] review-tui: read native_ansi_color for the trailer overlay header Konstantin Khorenko
@ 2026-09-15 20:32 ` Konstantin Ryabitsev
1 sibling, 0 replies; 3+ messages in thread
From: Konstantin Ryabitsev @ 2026-09-15 20:32 UTC (permalink / raw)
To: tools, Konstantin Khorenko
On Fri, 04 Sep 2026 16:59:50 +0200, Konstantin Khorenko wrote:
> tui: fix MissingStyle crash under Textual ansi themes
Applied, thanks!
[1/2] tui: fix MissingStyle crash under Textual ansi themes
commit: 99687c6f54873d234b49b33322fee011682f1cc9
[2/2] review-tui: read native_ansi_color for the trailer overlay header
commit: 7e16afe0473cf1a066dc1f5baf348d41f7911665
One thing you may want to consider as a follow-up:
There is one more Rich-invalid keyword left. On every non-ansi
theme (textual-dark, nord, gruvbox, ...) Textual generates
text-muted as 'auto 60%', so after your alpha strip it becomes
'auto', which Rich rejects the same way it rejects 'transparent':
unable to parse 'auto' as color; 'auto' is not a valid color
It doesn't happen today, because nothing currently reads
ts['text-muted'] -- it is only consumed as the $text-muted CSS
variable, which Textual resolves itself. However, this can become a trap
the future bug.
It can fold into the same guard:
if textual_color in ('transparent', 'auto'):
return 'default'
'auto' means "pick a readable foreground", so 'default' is the
closest good Rich equivalent.
Best regards,
--
Konstantin Ryabitsev <konstantin@linuxfoundation.org>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-15 20:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 14:59 [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes Konstantin Khorenko
2026-09-04 14:59 ` [PATCH b4 2/2] review-tui: read native_ansi_color for the trailer overlay header Konstantin Khorenko
2026-09-15 20:32 ` [PATCH b4 1/2] tui: fix MissingStyle crash under Textual ansi themes Konstantin Ryabitsev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox