fix(colours): v6 palettes without label sequences inherit the parent's labels - #79
Merged
Conversation
…s labels Issue #47 (Dasher-Windows): 'Yellow on Black' rendered with no yellow anywhere - labels invisible on the dark background. The v6 palette files author only defaultLabelColor; their groupColorInfo entries carry no label sequences, so GetNodeLabelColor fell through the empty sequences to the PARENT palette's group-specific label colours - the legacy Default palette supplies black - which won before the palette's own defaultLabel fallback could run. Fix: the v6 parser defaults empty group label colours (groupLabelColor / nodeLabelColorSequence) to the palette's OWN defaultLabelColor, mirroring what ParseLegacy has always done when building its groups. Explicit per-group sequences still win; palettes without defaultLabelColor keep the old parent-inheritance. Regression test: with 'Yellow on Black' selected, every opcode-5 text command must be #FFFFFF00. Verified 21/21 yellow post-fix (pre-fix: all #FF000000). Signed-off-by: will wade <willwade@gmail.com>
5 tasks
willwade
added a commit
to dasher-project/Dasher-Windows
that referenced
this pull request
Sep 1, 2026
… startup crash handler (#48) ## Summary Fixes #46 and #47, plus the PostHog-reported startup crash handler bug. DasherCore bumped to v0.2.17 (+ the palette fix branch pending merge). ### #46 — Window size/position not remembered between runs - New `WindowSettings` (`%APPDATA%\Dasher\window_settings.json`) with **mode-scoped bounds**: normal and direct/keyboard modes save separately, so quitting in direct mode never shrinks the next normal launch - Restored before first show (constructor, `WindowStartupLocation.Manual`); saved on close and on runtime mode switches - **Off-screen guard**: a saved position that no longer intersects any connected screen (unplugged monitor, DPI change) falls back to the AXAML default instead of stranding the window behind a bezel — requires a visible ~80px chunk, not just a pixel - **Maximized**: normal-state bounds are tracked continuously, so closing while maximized saves the *restore* bounds, not the maximized frame; maximized state restores for normal mode only ### #47 — Yellow on Black theme renders all black Root cause is **DasherCore-side**: v6 palette files author only `defaultLabelColor`; their groups carry no label sequences, so label resolution fell through to the **parent** palette's group-specific label colours — the legacy Default palette supplies **black** — which won before the palette's own yellow fallback. Fixed in DasherCore [PR #79](dasher-project/DasherCore#79) (v6 parser defaults empty group label colours to the palette's own `defaultLabel`, mirroring `ParseLegacy`); submodule pinned to that branch pending merge, re-pin to the tagged release after. - Windows-side engine-driven regression test: with "Yellow on Black" active, **every** opcode-5 text command must be `#FFFFFF00` (measured pre-fix: all `#FF000000`) - Benefits all frontends — same parser, same palette files ### Startup crash handler (PostHog: `SavedCrashException` ×2, 31 Aug) The top-level handler wrote to a hardcoded dev path (`C:\github\DasherProjects\crash.log`) — user machines don't have it, so the handler crashed *itself* with `DirectoryNotFoundException` and telemetry captured the secondary exception. Now writes the RFC 0009 envelope (`AnalyticsService.WriteCrashFile`, scrubbed + versioned) plus a plain-text `startup-crash.log` fallback under `%APPDATA%\Dasher`, and no longer blocks on `Console.ReadLine()`. ### DasherCore v0.2.17 ScanFiles skips bad entries; failed Realize latches engineError (#77); direct-mode shadow-buffer invariant test (#78). ## Verification - 40/40 DasherCore test suites green (incl. new label-colour regression) - 77/77 Windows tests green - Geometry restore/clamp logic verified by build + manual review (needs an eyeball pass: resize/move → relaunch; unplug-monitor fallback can't be tested locally) ## Type of change - [x] Bug fix - [x] New feature (window geometry) ## Definition of Done - [x] Build + tests green - [x] Regression tests added - [x] Commits signed off (DCO) <!-- greptile_comment --> <h3>Greptile Summary</h3> The PR adds mode-scoped window geometry persistence, corrects startup crash recording, updates DasherCore for palette and engine fixes, and adds a native-engine palette regression test. - Restores and saves separate normal and keyboard-mode window bounds, including maximized restore behavior and off-screen validation. - Records fatal startup exceptions under the user’s application-data directory without blocking or throwing from the handler. - Updates DasherCore and verifies Yellow-on-Black text commands use yellow labels. <h3>Confidence Score: 5/5</h3> The PR appears safe to merge. No blocking failure remains. <details><summary><h3>Important Files Changed</h3></summary> | Filename | Overview | |----------|----------| | src/Dasher.Windows/Views/MainWindow.axaml.cs | Adds geometry restoration, visibility validation, mode-scoped persistence, and tracker handling; the previously reported geometry defects are addressed at current HEAD. | | src/Dasher.Windows/Controls/WindowSettings.cs | Introduces resilient JSON persistence for separate normal and keyboard-mode bounds. | | src/Dasher.Windows/Program.cs | Replaces the hardcoded and blocking startup crash path with guarded application-data crash records. | | tests/Dasher.Windows.Tests/PaletteLabelColorTests.cs | Adds a native-engine regression test asserting Yellow-on-Black text commands use the expected yellow color. | | DasherCore | Advances the engine submodule for palette parsing and related engine corrections. | </details> <details open><summary><h3>Flowchart</h3></summary> ```mermaid %%{init: {'theme': 'neutral'}}%% flowchart TD A[Startup] --> B[Load pane and window settings] B --> C{Saved bounds usable?} C -->|Yes| D[Apply mode-scoped bounds] C -->|No| E[Keep AXAML defaults] D --> F[Track normal-state geometry] E --> F F --> G{Runtime pane switch?} G -->|Yes| H[Save outgoing mode bounds] H --> I[Apply entering mode layout and bounds] I --> F G -->|Close| J[Save active mode bounds] ``` </details> <sub>Reviews (7): Last reviewed commit: ["fix(window): one coherent DPI scale for ..."](01c08c6) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=58992149)</sub> <details><summary><h4>Context used (4)</h4></summary> - Knowledge Base — [Application lifecycle and startup](https://app.greptile.com/dasher-project/-/custom-context/knowledge-base/dasher-project/dasher-windows/-/docs/application-lifecycle.md) - Knowledge Base — [Desktop UI composition](https://app.greptile.com/dasher-project/-/custom-context/knowledge-base/dasher-project/dasher-windows/-/docs/desktop-ui.md) - Knowledge Base — [Settings panels and text output](https://app.greptile.com/dasher-project/-/custom-context/knowledge-base/dasher-project/dasher-windows/-/docs/settings-and-output.md) - Knowledge Base — [Automated validation](https://app.greptile.com/dasher-project/-/custom-context/knowledge-base/dasher-project/dasher-windows/-/docs/automated-validation.md) </details> <!-- /greptile_comment --> --------- Signed-off-by: will wade <willwade@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes Dasher-Windows #47: "Yellow on Black colour theme — it's all black. The font is not yellow. There is no yellow anywhere."
Root cause
The v6 palette files (
Data/colors/color.*.xml, RFC 0007) are authored with onlydefaultLabelColorand no per-group label sequences. Label resolution inGetNodeLabelColor/GetGroupLabelColortreats the empty sequences as "undefined" and falls through to the parent palette — whose group-specific label colours win before the child palette's owndefaultLabelfallback can run. For "Yellow on Black" (parentName="Default"), the legacy Default palette supplies black labels → invisible on the dark background.Fix
The v6 parser now defaults empty group label colours (
groupLabelColor/nodeLabelColorSequence) to the palette's owndefaultLabelColor— mirroring whatParseLegacyhas always done when building its groups (ColorIO.cpp:105-128). Explicit per-group sequences still win; palettes that don't definedefaultLabelColorkeep the previous parent-inheritance behaviour.Regression test
yellow_on_black_labels_carry_palette_default_label_colour(test_draw_commands.cpp): with "Yellow on Black" selected, every opcode-5 text command must be#FFFFFF00. Measured pre-fix: all#FF000000; post-fix: 21/21 yellow.Full suite: 40/40 test executables green (incl. the #63 uppercase-colour regression, which shares this code path).
Notes
Type of change
Definition of Done
Greptile Summary
The PR updates v6 palette parsing so groups with no explicit label colors use their palette’s own
defaultLabelColor, preventing parent group colors from overriding intended high-contrast labels.Confidence Score: 5/5
The PR appears safe to merge with no actionable correctness, security, or quality issues identified.
The parser change is scoped to wholly unspecified label colors, preserves explicit definitions and no-default inheritance, and the regression test exercises the resulting frontend-visible draw commands.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR A[v6 palette group] --> B{Explicit label colors?} B -->|Yes| C[Use explicit group or node colors] B -->|No| D{Palette defines defaultLabelColor?} D -->|Yes| E[Materialize palette-local label default] D -->|No| F[Retain parent inheritance] C --> G[Render labels] E --> G F --> GReviews (1): Last reviewed commit: "fix(colours): v6 palettes without label ..." | Re-trigger Greptile
Context used: