From a24e9a8d768f7ccde73c30bbc6efd3d4d93f95fb Mon Sep 17 00:00:00 2001 From: will wade Date: Sat, 20 Jun 2026 06:40:17 +0100 Subject: [PATCH] Fix appearance model: late-seed dark companion after Realize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ensureAppearanceInitialised seeds the dark preference by looking up the current palette's companion. But frontends typically call dasher_set_system_appearance from their .onAppear handler, which fires BEFORE Realize() (and before ColorIO is populated). At that point the companion lookup fails, darkPalette stays empty, and once appearanceLoaded is set to true the seed is never retried. Result: system appearance changes never flip the palette — resolveAppearance picks an empty darkPalette, falls back to an empty lightPalette, and returns without doing anything. Fix: add a late-seed check in resolveAppearance. If darkPalette is empty but lightPalette is set and ColorIO is now available, retry the companion lookup. This runs on every resolveAppearance call, so once Realize completes and the next system-appearance change (or mode change) arrives, the companion is found and dark mode works. Signed-off-by: will wade --- src/CAPI.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/CAPI.cpp b/src/CAPI.cpp index 4550770d..52d0a278 100644 --- a/src/CAPI.cpp +++ b/src/CAPI.cpp @@ -541,6 +541,17 @@ int effectiveAppearanceValue(const dasher_ctx* ctx) { // source of truth, so this can never clobber the user's explicit choice. void resolveAppearance(dasher_ctx* ctx) { if (!ctx || !ctx->intf) return; + + // Late seed: ensureAppearanceInitialised may have run before Realize, + // when ColorIO wasn't available and the companion lookup failed. + // Retry now — once ColorIO exists, the lookup succeeds and fills the gap. + if (ctx->darkPalette.empty() && !ctx->lightPalette.empty()) { + if (auto* colorIO = ctx->intf->GetColorIO()) { + if (const Dasher::ColorPalette* comp = companionLookup(colorIO, ctx->lightPalette)) + ctx->darkPalette = comp->PaletteName; + } + } + int eff = effectiveAppearanceValue(ctx); std::string target = (eff == 1) ? ctx->lightPalette : ctx->darkPalette; if (target.empty()) target = (eff == 1) ? ctx->darkPalette : ctx->lightPalette; // other side