CosmicToast/starlight

color scheme and dialog(1)

Closed this issue · 8 comments

Plain old dialog doesn't look very readable with the starlight theme as used in e.g. foot.
See eg. dialog --backtitle title --msgbox test 0 0 in foot vs xterm :

Screenshot_20230905_140614

Any chance to tune the colors to work better with dialog?

This looks like a contrast issue between blue and cyan, which generally aren't meant to be opposed like that.

The way this is typically achieved in (e.g xterm defaults, as shown here) is by making the blue significantly darker.
However, that makes it illegible for me on black (the default background), which is a much worse situation to be in.
The converse is seemingly not possible, as the cyan is already pushing the upper luminance boundary.

In short, this is a dialog problem, and it's possible that dialog being this way is what makes the vast majority of blues in ASCII themes impossible for me to read.

To summarize, this could be fixed in one of three ways:

  • Make the blue darker. This would go against the point of the theme, as having a contrast high enough would make it illegible on black, which is worse than having cyan not legible on blue.
  • Make the cyan lighter. This is impossible, since it's already against the upper sRGB boundary.
  • Make dialog saner. As far as I can tell, there's no reason other than aesthetic for them to be using blue as a background. I would recommend they use the standard ASCII background color (whichever is used by the terminal) & have a border.

So basically, dialog makes this impossible to fix without either patching it, or making the theme strictly unusable.
I do wish I could help, but this is a self-inflicted (by dialog) issue.

I took a look at patching it, but it seems like they don't even have support for default foreground or background macros (or even bright variants of colors).
Regardless, this is what it looks like when the following patch is applied:

diff --git a/dlg_colors.h.orig b/dlg_colors.h
index de91627..1ca9fd1 100644
--- a/dlg_colors.h
+++ b/dlg_colors.h
@@ -38,8 +38,8 @@
  *   DLGC_UL_xxx = underline for "xxx"
  *   DLGC_RV_xxx = reverse for "xxx"
  */
-#define DLGC_FG_SCREEN                 COLOR_CYAN
-#define DLGC_BG_SCREEN                 COLOR_BLUE
+#define DLGC_FG_SCREEN                 COLOR_WHITE
+#define DLGC_BG_SCREEN                 COLOR_BLACK
 #define DLGC_HL_SCREEN                 TRUE
 #define DLGC_UL_SCREEN                 FALSE
 #define DLGC_RV_SCREEN                 FALSE
image

FTR, dialog colors are configurable, e.g. with screen_color = (WHITE,BLACK,ON) in ~/.dialogrc

in that screenshot there's actually a contrast with white on white in the dialog borders. Looks like in foot the highlight property doesn't work. Is that a bug in foot or the theme?

I looked at it a bit, and (if I'm not mistaken), dialog seems to use CSI [0;1m in order to create "highlight"s.
Spec-wise, this is "bold or increased intensity", and foot defaults to bold only (see option bold-text-in-bright in foot.ini(5)).
As far as I can tell, Xterm defaults to having this behavior (though it's hard to figure out which option it is exactly, as Xterm often does).
Can you try setting bold-text-in-bright to palette-based or yes and see if that fixes it @lnussel ?

If that helps, then it's neither a foot bug nor an issue with the theme, but rather just a configuration default (plenty of people don't think bold should imply a brighter color, but dialog expects very specific (typically debian default) configurations).

As an aside, this is entirely on dialog once again, if they want a brighter color, the correct option would be to use the brighter color variant. They just appear to have never actually added the internal macros to get the right escape codes to do so.

Setting bold-text-in-bright to either works, thanks!
I don't know the first thing about such things but dialog has been there for like forever and seems to work in both xterm and the Linux console as expected. So I those modern terminals should probably be compatible out of the box.

I'll explain why things are the way there are for a little bit, but I'll start with the short version:
The compatibility is based on a misunderstanding of the specification (specifically ECMA-48, ISO/IEC 6429, FIPS 86, ANSI X3.64, JIS X 0211, all same spec, I will be citing ECMA-48 in particular).
In section 8.3.117 (CSI Ps... 06/13) with Parameter string of 1 indicates "bold or increased intensity" (emphasis mine).
The intent was to have some way to (indeed) highlight a particular set of text (emphasis mine) that is particularly relevant among other text.
Xterm defaulted to doing both, and the people behind dialog (I think it was Stuart Herbert in particular that was to blame for this one, but this may be wrong) presumed that that's what the spec said (that it was an and).
The problem is that under that setting, it becomes impossible to have bold text that is not brighter than text of the same color (unless, potentially, it is already "brightened", depending on the implementation).
This is obviously an issue for application developers, which use ECMA-48 style escape sequences for all sorts of stuff nowadays, and therefore is not a reasonable default to have, as it will break all sorts of other stuff.

The long version Around the time of Slackware 1.1 (specifically 1.1.2), there was a lot of desire to make Linux seem more "professional". "Professional" at the time meant "close to DOS". DOS had its own filesystem (UMSDOS) and color support. So, Slackware 1.1.2 added support for the UMSDOS filesystem, which meant that people with enough bits in their funny boxes could install Linux alongside their existing DOS install. In addition to that, Patrick Volkerding wrote dialog-based (the Savio Lam version) setup scripts for that release, and Ian Klut integrated them into the overall system, so now Slackware had the "professional" look, at least while you installed it. If you've ever wondered why dialog (under traditional ANSI colors) kind of looks like it came straight out of Windows 98, it's because it is like this on purpose. (As an aside, I might note that Windows has long since abandoned this "installer" look, for similar enough reasons as to why this type of tool is being abandoned nowadays - it's got many unfortunate decisions).

Since the goal was to simply mimick whatever DOS was doing and accessibility wasn't a real concern for computer users (not that many people actually had computers in 1993-1994), using 8bit colors seemed fine, so that's what was used.
Not only that, but the specific historical ANSI colors were used, which meant that the color names might as well (and potentially should!) simply be truecolor sequences for those exact colors - in what other world does putting "darker cyan text" over "darker blue backgroun" would make sense?
When dialog was later rewritten by Thomas Dickey of ncurses fame, compatibility meant keeping those colors.

In the meanwhile, the specifications had to deal with something entirely different.
Around the time of the release of ECAM-48 (1976), you still had physical TTYs (teletypers) around, which did not always have support for colors, or did not have support for switching their fonts to "bold".
The intent of the "1" Parameter string to SGI was to highlight important text, and since some devices around at the time could only do different colors (see: other SGI entries) while others could only do different fonts (ditto), the specification defined it as an or.
The logic (as far as I can tell) of Xterm doing both was similar - it was released in (literally) 1984, and there was no guarantee that your computer font would have a "bold" variant, and therefore defaulting to doing both was safe.

Since one of the main uses of dialog soon after its birth was to mimick the at-the-time concept of "professionalism", the exact implementation details (i.e reading the spec) was not a concern, and things were simply tested against known environments.
Consequently, we ended up with the presumption inside of dialog that "1" would brighten whatever text there is.

So the dialog constraints were:

  1. It only used 8bit colors due to historical details.
  2. It wanted to brighten colors.
  3. It happened to work on Xterm and the BSD consoles.
    Conclusion: ship it.

This is particularly interesting since to perform line drawing, ECMA-35 alternative character sets are used.
What is a "bold" version of "ACS_DIAMOND"?
Of course, the correct thing to do would have been to simply set the foreground color to the brighter variant of white, but due to constraint 1, they couldn't do that.
And hey, it was more about hacks at the time, "1 neat trick terminal emulator developers will hate for decades to come".

So in short, this is a problem with dialog wanting 16 colors but not being willing to support 16 colors, and instead relying on a historical implementation detail caused by physical teletypers and early terminal emulators on w/b screens interacting with specifications written to support potentially both of those without modifications in the 1970s.
Hope this clears things up!
The correct thing to do would be, ultimately, to patch dialog, but I have little desire (or hope) when it comes to sending breaking patches in Dickey's direction, considering Debian's policies when it comes to breaking changes in the base system (which have (in my opinion) undue consideration in the distribution development community).

What a mess! Thanks a lot for this explanation! Could fill an entire talk at fosdem I guess ;)