Skip to content

TUI: orderbook renders unreadable colours on macOS Terminal.app (truecolor RGB not supported) #36

@llcro

Description

@llcro

Reported by

Screenshot attached in thread.

Symptom

On the Market Detail orderbook (and likely other panels), font colours look random — including black-on-dark text that is effectively invisible.

Environment:

  • macOS Terminal.app (stock, personal laptop)
  • Theme: terminal-pro (default)
  • No custom ANSI escape settings in zshrc/bashrc
  • Works correctly on a different machine (company MBP — likely iTerm2)

Root cause (high-confidence hypothesis)

macOS Terminal.app does not support 24-bit truecolor ANSI escapes (\e[38;2;R;G;Bm). It is capped at 256-indexed colour. Our themes (crates/cdcx-tui/src/theme.rs) and several widgets emit Color::Rgb(...) unconditionally:

  • terminal-pro fg = Color::Rgb(220, 220, 220), bg = Color::Rgb(18, 18, 18), muted = Color::Rgb(120, 120, 120), etc. (theme.rs:50–69)
  • Orderbook depth bars + heatmap use Color::Rgb gradients (widgets/detail_view.rs:500–525, tabs/market.rs:1700+)
  • Pressure-bar background = Color::Rgb(0, 30, 0) / Color::Rgb(30, 0, 0) (detail_view.rs:355–373)

When Terminal.app receives a truecolor sequence it doesn't understand, behaviour varies: some chunks are dropped, some fall back to default fg (which may be black on his profile), some map poorly — producing the "random" palette Alan is seeing.

The cursor-selected Ask row also uses selected_fg: Color::Black on selected_bg: Color::Rgb(255,180,0); if the bg RGB fails to render but fg Black succeeds, you get black-on-dark → invisible.

Reproduction

  1. Launch macOS Terminal.app (default settings).
  2. cargo run -p cdcx-cli --release -- tui
  3. Enter Detail view on any instrument.
  4. Observe orderbook — colours are random, some text is unreadable.

Not reproducible on iTerm2, Ghostty, Alacritty, Kitty, WezTerm (all support truecolor).

Suggested fixes

Ranked by cost/benefit:

  1. Detect truecolor support at startup, downgrade to 256-indexed colour when absent.

    • Check $COLORTERM == "truecolor" or "24bit" (standard signalling).
    • If absent, fall back to a 256-indexed palette: convert every Color::Rgb(r,g,b) via nearest-256-colour mapping or ship parallel indexed themes.
    • Smallest user-facing change; no UX regression on capable terminals.
  2. Ship a 256-indexed preset theme (e.g. terminal-pro-256) and document it in the setup wizard / README — users on Terminal.app pick it explicitly. Simpler to implement but requires user knowledge.

  3. Hard-guard Terminal.app via TERM_PROGRAM=Apple_Terminal and auto-swap to the indexed theme. Cheap to detect but narrow.

The right move is probably (1) + a --no-truecolor / tui.force_256 = true override so users whose detection misfires can opt in manually.

Scope of blast radius

Every Color::Rgb call site in crates/cdcx-tui/. Theme definitions in theme.rs are the big one; widget-level gradients (detail_view.rs, market.rs, ticker_tape.rs, heatmap, depth bars) all need the same downgrade path.

Acceptance

  • cdcx tui is fully readable on macOS Terminal.app with the default theme.
  • Existing truecolor terminals look identical to today.
  • Fallback palette documented; override env var / config flag exists.
  • Smoke-tested on: Terminal.app, iTerm2, Ghostty, Alacritty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions