ADR: EditorColor Registry Consistency¶
Status¶
Proposed (Date: 2026-08-02)
Context¶
org.omegat.util.gui.Styles.EditorColor is the registry that mediates between Theme,
application code, and Preferences for every segment marker colour (see the mechanism
reference in 84.ThemeColorAndPresentation.md). An audit
of the enum, done while reviewing ADR 2026003,
found that its ~50 entries are declared through three different constructors, each with a
different default-resolution behaviour:
Two-argument, theme-backed (the majority of entries): the default is
UIManager.getColor("OmegaT.xxx"), i.e. whatever the active theme defines. Example:COLOR_ACTIVE_SOURCE(displayName, UIManager.getColor("OmegaT.activeSource")).Three-argument, hardcoded fallback (3 entries — the Source Files progress colours): the default is
UIManager.getColor(uiManagerKey)if present, otherwise a literal hex colour compiled intoStyles.java:COLOR_PROJECT_FILES_PROGRESS_LOW(displayName, "OmegaT.projectFilesProgressLow", "#f0b8b4"), COLOR_PROJECT_FILES_PROGRESS_HIGH(displayName, "OmegaT.projectFilesProgressHigh", "#b7d7b7"), COLOR_PROJECT_FILES_PROGRESS_COMPLETE(displayName, "OmegaT.projectFilesProgressComplete", "#b8ccf0"),
Neither
DefaultFlatLightThemenorDefaultFlatDarkThemedefines these threeOmegaT.*keys, so the hardcoded literal is not a rare fallback — it is the value every user of the two bundled themes actually gets today.One-argument, no theme default (roughly 15 entries):
defaultColorisnullat construction, and the resolved colour staysnullunless a Preferences value has been set. NoOmegaT.*UIDefaults key exists for these at all, in either bundled theme. Example:COLOR_ACTIVE_TARGET(displayName), and similarlyCOLOR_ACTIVE_SOURCE_FG,COLOR_ACTIVE_TARGET_FG,COLOR_SEGMENT_MARKER_FG,COLOR_SEGMENT_MARKER_BG,COLOR_SOURCE_FG,COLOR_NOTED_FG,COLOR_UNTRANSLATED_FG,COLOR_TRANSLATED_FG,COLOR_NON_UNIQUE_BG,COLOR_MOD_INFO,COLOR_MOD_INFO_FG,COLOR_GLOSSARY_SOURCE,COLOR_GLOSSARY_TARGET,COLOR_GLOSSARY_NOTE,COLOR_MATCHES_DEL_ACTIVE,COLOR_MATCHES_DEL_INACTIVE. Consumers such asEditorSettings.getAttributeSet()call.getColor()on these directly and pass the (possibly null) result straight intoStyles.createAttributeSet(); there is no null-handling fallback at the call site either.
Pattern (2) means a theme author has no reliable way to make the Source Files progress colours part of their palette without also relying on undocumented code-level defaults. Pattern (3) means a theme author — including a hypothetical high-contrast/accessibility theme, one of the options raised in the persona review behind 2026003 — cannot control those ~15 markers via the Theme layer at all; the only way to set them is per-user Preferences, which is not something a theme can ship.
This is directly relevant to 2026003. That ADR’s decision is to extend the theme-to-registry- to-preference chain to additional presentation channels (formatting, audio, accessibility labels) uniformly across markers. Doing that on top of the current registry means propagating three inconsistent default-resolution patterns across N new channels instead of one. It is cheaper to unify the registry first.
Decision¶
Decision A. Every EditorColor entry will have a real, theme-resolvable default,
reached via the standard two-argument, theme-backed constructor:
The three Source Files progress colours gain corresponding
OmegaT.*keys in bothDefaultFlatLightThemeandDefaultFlatDarkTheme, and move off the three-argument constructor.The ~15 theme-less entries gain corresponding
OmegaT.*keys in both bundled themes as well, and move off the one-argument constructor.
This is an architecture decision, not a design decision: it is about where each default lives (theme-backed key vs. hardcoded literal vs. absent), not about what the colour values should be. Selecting the actual colour values is an implementation detail left to the PR that carries out this change, not decided here. In particular, no visual change is intended as a result of this ADR: for the three progress-colour entries a value already exists (the current hardcoded literal) and the expectation is that it carries over unchanged; this ADR does not mandate that expectation, it simply is not proposing a redesign.
Decision B. Once Decision A is complete, remove the one-argument and three-argument
EditorColor constructors entirely, leaving a single canonical two-argument, theme-backed
constructor. This is a deliberate constraint on the enum’s API surface so that a future
contributor — including whoever implements 2026003’s additional channels — cannot
reintroduce a theme-less or hardcoded-fallback entry.
The existing ColorScheme_{dark,light}.properties fallback in UIDesignManager (used only
when a third-party theme omits OmegaT.* keys entirely) is unaffected by this decision; it
remains the safety net for incomplete external themes, which is a different concern from the
two bundled themes carrying inconsistent defaults internally.
Consequences¶
Positive¶
Every marker becomes fully definable by a theme, which is required groundwork for a high-contrast or otherwise accessibility-oriented theme, one of the resolutions proposed in 2026003 for the persona review’s contrast-audit item.
2026003’s planned extension of the registry to formatting/audio/accessibility-label channels can follow one constructor pattern instead of reconciling three.
Removes a currently silent behaviour (the hardcoded progress-colour fallback applies to the bundled themes today, not just hypothetical incomplete ones) that no theme author can override short of also touching Preferences.
Negative¶
Requires adding ~18 new keys to both
DefaultFlatLightThemeandDefaultFlatDarkTheme. Colour value selection for this is out of scope of this ADR and left to the implementation PR; it is not a purely mechanical change for the ~15 entries that have never had a theme-backed value before, since there is nothing existing to carry over for those.Any third-party theme plugin, or a user relying on the current “null means inherit component default” behaviour for one of the fifteen theme-less markers, may see a visible colour change once a real default is introduced there. This risk does not apply to the three progress-colour entries, where the existing hardcoded literal is expected to carry over unchanged.
Removing the one- and three-argument constructors is a breaking change to
Styles.java’s internal API surface (not a public/plugin API, but touches every affected enum literal in one changeset).