87509bcf99
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.
3.4 KiB
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:
- Exactly ONE background per screen, named "Background", at position 0.
- It cannot be re-ordered or deleted; no Background/Screen item in the (+) menu.
- Context-sensitivity exists only on the Live screen (Show Desktop toggle + monitor switching — behavior kept intact).
- 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 =DisplayCapturerow (capture machinery untouched), everything else = staticBackgroundart 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 derivesIsBackground— 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.jpgviaAddAsset; 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 orphanedBackgroundUseDefault_{guid}keys. - Settings purge:
LayoutStore.SavedeletesBackgroundUseDefault_{id}/BackgroundPath_{id}keys whose id is no longer a Source row. - (+) menu: Screen + Background items removed → Webcam/Image/Text/Countdown/Web/YouTube Chat;
AddSourcealso 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'sIsBackgroundthrough a newHelpers/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 makingLoadBackgroundImageflavor-blind (IsBackground) and gating staged-Live to the placeholder inRefreshSnapshotsAsync. (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.