Files
LlamaCasty/TASKS/task-25-background-consolidation.md
gramps 87509bcf99 docs: restructure TASKS.md into a catalog — one file per task in TASKS/
TASKS.md is now the index (status table, open items, research pointer).
33 files: 32 task files + 1 research facts file. The full take-saga
narrative and all design decisions are preserved verbatim; the catalog
makes the queue readable without opening every task body. Schema and
AGENTS.md updated to reflect the new layout.
2026-09-05 16:31:46 -07:00

3.4 KiB

TASK 25 — Background consolidation: one locked Background per screen + mini-view rule

Catalog: TASKS.md — status and requirements live here.

Status: ✅ Done (shipped 2026-08-23, branch task25-backgrounds)

The creator rejected the multi-concept background model ("why are there multiple background things?"). Locked model, verbatim intent:

  1. Exactly ONE background per screen, named "Background", at position 0.
  2. It cannot be re-ordered or deleted; no Background/Screen item in the (+) menu.
  3. Context-sensitivity exists only on the Live screen (Show Desktop toggle + monitor switching — behavior kept intact).
  4. Exactly five default background images live in the DB; stale rows are cleaned up.

What shipped:

  • Seeder consolidation: the five near-clone seeders (Seed{Starting,Brb,Ending,Chat}Background, SeedLiveBackgroundAsset, EnsureDefaultBackground) are gone. One path now: EnsureBackground(scene) → CreateBackground(name) — Live = DisplayCapture row (capture machinery untouched), everything else = static Background art row; both named "Background".
  • Heal on every load: NormalizeBackgrounds(scenes) keeps the correctly-flavored row, converts a wrong-flavor survivor in place (Source.Type's setter derives IsBackground — conversions must re-assert the flag), drops duplicates, seeds missing ones, renames, pins to index 0; non-canonical scenes lose backgrounds + flag. HealBackgrounds() stamps default art (Assets/{scene}-background.jpg via AddAsset; custom Browse art wins). This fixed the real DB's rot: four scenes carried a stray "Game Capture" duplicate beside their static row, and Settings held 16 orphaned BackgroundUseDefault_{guid} keys.
  • Settings purge: LayoutStore.Save deletes BackgroundUseDefault_{id} / BackgroundPath_{id} keys whose id is no longer a Source row.
  • (+) menu: Screen + Background items removed → Webcam/Image/Text/Countdown/Web/YouTube Chat; AddSource also hard-refuses DisplayCapture/WindowCapture/Background parameters.
  • Capture controls Live-only: CanChangeBackground = staged scene is Live. The preview CanvasGrid menu (Show Desktop/Capture Desktop/Refresh Desktop) binds it directly; the layer-row context menu MultiBindings it with the row's IsBackground through a new Helpers/AllTrueToVisibilityConverter. Non-Live screens keep the Use-default pill + Browse.
  • Mini rule: minis never render live captures. While Live is staged its mini shows the green placeholder; unstaged it shows live-background.jpg. Fixed by making LoadBackgroundImage flavor-blind (IsBackground) and gating staged-Live to the placeholder in RefreshSnapshotsAsync. (Real-time rendering stays center-monitor-only — preview lag during live gameplay is a known unsolved OS-level problem and must not be compounded.)

Tests (suite went 221/218 → 223/220; the two stale background-policy landmine tests healed here):

  • Integration (the ONE): BackgroundHealIntegrationTests — seeds a dirty temp DB (duplicate rows, misnamed Live row, orphaned keys), drives the real window, asserts one Background per scene at index 0 with correct flavor/name, save purges the orphaned keys.
  • Unit: SceneCatalogTests rewritten for NormalizeBackgrounds/EnsureBackground flavors; BackgroundTests empty-scene flavor updated; SourceNamingTests excludes the always-present Background from numbered-name expectations.