cmang/durdraw

Background Colors in 256 color mode

cmang opened this issue · 1 comments

Background colors only work in 16 color mode, and do not work in 256 color mode. This is because Python curses is unable to set color pairs past 256 pairs. This is enough pairs for all of the 16 FG and 16 BG color combinations, but not 256 FG and 256 BG color combinations.

Python has a method, curses.has_extended_color_support(), which is supposed to return True if more than 256 color pairs are supported. In this case, using Python 3.10, 3.11, and (I think) 3.12, the method returns True in macOS and the Linux systems I've tried. Even if the Python builds are compiled against Ncurses 5... which is a problem, because extended color pairs only work with the Ncurses 6 ABI.

So, when you try to set or use color pairs past 256, they do not work. No errors are returned. But they seem to wrap back around to write or read from color pair 1. For example, trying to read color pair 257 instead reads pair 1, pair 258 instead reads pair 2, etc. Writing pair 257 either overwrites pair 1, or seems to disappear into /dev/null. I think this is a bug in Python's extended color support.

I have seen this behavior in macOS and Linux systems. Python bug report #91132 seems to hint at the cause, which is that Python for macOS is compiled against Ncurses 5.9. This implies that it's using the Ncuress 5 ABI, which means that curses.has_extended_color_support() should be False, even though it isn't. (Python bug?)

I can think of 3 possible ways to fix this:

1: Only generate the color pairs that are needed, and hope the user never needs more than 256 pairs. This is not great, though, because Durdraw displays the entire 256 color palette on the screen at once. This means that all 256 color pairs are already in use. As an artist, I like seeing the entire palette at once and don't want to trade away that feature. So I am not crazy about this idea. (It might work nicely for RGB colors, though.)

2: Use a Python build that actually works with extended color pairs. I have not been able to get my hands on one yet, but this is the direction I have been leaning. We can wait for OS vendors and Python core developers to dsitribute Python binaries compiled correctly against the Ncurses 6 ABI, and fix the bugs with extended color pair reporting. This would be nice, but we don't seem to be there yet.

3: Steer away from using Ncurses all together for generating color escape codes. They might be able to be injected with puts() or something, but this breaks ncurses convention and may break across different ncurses versions. Or, ncurses might be replaced with another library completely. This would be a lot of work with refactoring and rewriting Durdraw code. It might also break some portability. I don't like this option, either. :)

After more research, I'm pretty sure that extended color pairs in Python are currently just broken.

I have filed a bug report with cpython about the extended color pairs not displaying correctly. If that can get fixed, then we should be able to get extended background colors working in Durdraw.