Skip to content

ImGuiPaletteMapper makes selected text unreadable in all 38 themes (Text on TextSelectedBg ≈ 2:1), and slider grabs / plot lines barely show against FrameBg #116

Description

@matt-edmondson

What's wrong

ImGuiPaletteMapper chooses priorities that put several foreground/background pairs ImGui draws on top of each other at almost the same lightness. The worst case is text selection.

TextSelectedBg is mapped to (Alternate, High) (ThemeProvider.ImGui/ImGuiPaletteMapper.cs:94) and is fully opaque. In a focused InputText, ImGui fills the selection rectangle with that colour and then draws Text (Neutral, VeryHigh) on top of it. For comparison, ImGui's own default is translucent: (0.26, 0.59, 0.98, 0.35).

Contrast ratios from new ImGuiPaletteMapper().MapTheme(theme), measured over all 38 themes in ThemeRegistry.AllThemes at 9454d42:

Pair (foreground on background) Mapping lines Lowest Median Themes below threshold
Text on TextSelectedBg :94, :44 1.45 1.97 38 of 38 below 3:1
SliderGrab (Primary MediumLow) on FrameBg (Neutral Low) :70, :40 1.34 1.85 38 of 38 below 3:1
PlotLines (Alternate Medium) on FrameBg :82, :40 1.69 2.38 36 of 38 below 3:1
Text on FrameBgActive (Neutral Medium) :44, :42 2.37 3.27 38 of 38 below 4.5:1

Worst cases:

  • VSCode Light: selected text is #000000 on #4a005e, a ratio of 1.45, so it effectively disappears.
  • Everforest Light: selected text is #5c6a72 on #dc6902 (1.61), and the slider grab is #afc541 on #d8d8c8.
  • Catppuccin Mocha: selected text is #cdd6f4 on #b787aa (2.06).

WCAG sets 4.5:1 as the minimum for body text and 3:1 for non-text UI parts. The only contrast test today, MapTheme_TextContrastsWithWindowBackground, only asserts that Text and WindowBg are not identical.

Suggested fix

  • TextSelectedBg: map it to a low accent priority (VeryLow or Low, as Button does) and/or give it a translucent alpha, so Text keeps its contrast.
  • SliderGrab and PlotLines/PlotHistogram: move them toward the high-visibility end, the way CheckMark uses VeryHigh.
  • FrameBgActive: keep it near Low or MediumLow, so text inside an active frame stays readable.

Acceptance criteria

Add a test that iterates ThemeRegistry.AllThemes and asserts these minimums:

  • Text on TextSelectedBg and on FrameBgActive: at least 4.5:1.
  • SliderGrab, PlotLines and CheckMark on FrameBg: at least 3:1.

This is separate from #110, which covers ImGuiCol slots that are not mapped at all, and #114, which covers VeryHigh neutral tinting.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions