Footer with ANSI colors broken in v3.1.0
As mentioned in #5862, the footer descriptions are unreadable when ansi_colors=True in the app. Unfortunately it looks like the footer colors were broken in Textual v3.1.0.
Here's a comparison showing the footer example from the docs but ran with app = FooterApp(ansi_color=True):
v3.0.0
v3.1.0
Setting the theme to textual-ansi doesn't help:
We found the following entries in the FAQ which you may find helpful:
Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.
This is an automated reply, generated by FAQtory
Having just learned about ansi_colors=True recently, I had assumed this was always a problem. If this is a new issue then I would also really like to see it fixed
Would either of you like to tackle this one? Ping me if you need any assistance.
@willmcgugan I did spend a fair while looking into this, but unless I'm missing something obvious, this isn't easy to track down. I'm happy to have another crack at it, but I'm afraid I'll need a hint!
so I did some digging into this myself. I found a kind of related solution, I believe. Which is that in my opinion, if there is a footer in the app then it shouldn't be affected by transparency. My guess would be that most people would expect that the footer will stay opaque. So, in my own testing I have done this
Replacing at widgets/_footer.py line 144 https://github.com/Textualize/textual/blob/6e4f77bb48080aacac03c6141eeed0cf11b5e92e/src/textual/widgets/_footer.py#L144
&:ansi {
/* background: ansi_default; */
.footer-key--key {
/* background: ansi_default; */
color: ansi_magenta;
}
.footer-key--description {
/* background: ansi_default; */
color: ansi_default;
}
FooterKey:hover {
text-style: underline;
/* background: ansi_default; */
color: ansi_default;
.footer-key--key {
/* background: ansi_default; */
}
}
FooterKey.-command-palette {
/* background: ansi_default; */
border-left: vkey ansi_black;
}
}
}
Now I have no idea if this would be acceptable, I'm just brainstorming. From what I can tell, most of Textual does not change when ansi_color is set to True? Most widgets retain their colors, its not dropping the entire app immediately down to 16 colors or anything like that.
So what I'm wondering here is, can we possibly just prevent the Footer from changing the background as I've done above? In my own testing in Windows Terminal, this basically solves the problem. Like I said I would expect that the footer stays opaque.
@edward-jazzhands I don't think this is the fix I'm afraid. Have you tried also setting the theme to textual-ansi?
Ah, no I had not tried that. I was setting the ansi_color = True variable on the app. Either when creating an app with TextualApp(ansi_color=True).run() or by setting self.ansi_color = True on the app class.
It seems that using the ansi_color=True variable works and looks great, because its not dropping every color in the app down to 16 colors. Whereas setting self.theme = "textual-ansi" actually forces the entire app down to 16 colors. You should also try it out if you have not already to see the difference.
At this point I would like to recommend thinking of this as two different problems. Transparency with ansi_color=True looks great, because all its doing is enabling transparency without forcing the entire app down to 16 colors. self.theme = "textual-ansi" is doing the latter and creates and entirely new set of problems. It should be possible to enable transparency without forcing the app into 16 colors. I think a proper solution might need to account for both situations.
I deleted my previous post as it didn't really explain the problem.
Regardless of the theme, previously background: ansi_default worked the same in the Footer as all other widgets that set this in the :ansi pseudo class.
This ANSI theming isn't really documented (and according to the FAQ doesn't even exist!), so perhaps I have just misunderstood how this is supposed to work.
I've had another crack at this, but I'm afraid I still don't know how to fix it.
The Footer is composed of FooterKey widgets. These render Rich Text which gets converted to Textual Content objects.
The problem is that this converts the background Color('default', ColorType.DEFAULT) to Color(217, 217, 217).
Following the code path from visual.py -> content.py -> style.py -> color.py:
https://github.com/Textualize/textual/blob/11580e999adb7fb5104edbb4ed28c50997944993/src/textual/color.py#L195
The problem is that this will return the theme foreground color:
else: # self.type == ColorType.DEFAULT:
assert self.number is None
return theme.foreground_color if foreground else theme.background_color
When background: ansi_default, presumably we don't actually want any background color?