AppTheme.isDark is een statische vlag: oppervlakken blijven na een themawissel in de vorige kleuren staan #814
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#814
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Wat er aan de hand is
AppTheme.isDarkis een statische vlag. De mode-afhankelijke tokens(
slate600,successBg,paper, …) zijn getters die hem uitlezen. Dat iseen bewuste keuze: een dia moet in een headless export-isolate identiek
renderen aan de preview, en daar bestaat geen
BuildContext(PENTEST_MIAUW §11).
Maar een statische vlag is geen
InheritedWidget. Wie hem uitleest, krijgtgeen melding als hij verandert. Het gevolg: élke widget die zich uit
AppThemekleurt en niet vanTheme.of(context)afhangt, houdt na eenthemawisseling de kleuren van het vórige thema vast — tot iets anders hem
toevallig laat herbouwen, of tot een herstart.
Gevonden in #780 aan het slidekwaliteitspaneel: dat bleef donkergroen op een
lichte interface staan. Een andere dia kiezen hielp niet, in- en uitklappen
hielp niet. Dat paneel is gerepareerd; de klasse niet.
Wat er al staat
lib/theme/appearance_scope.dartpubliceert de modus alsInheritedWidget.Een oppervlak sluit erop aan met één regel:
Het kwaliteitspaneel en zijn chip hebben die regel;
test/appearance_scope_test.dartbewaakt het mechanisme en een bronwacht in
test/slide_quality_panel_contrast_test.dartbewaakt dat díe twee hem houden.Wat er níet werkt — niet nog eens proberen
De voor de hand liggende oplossing is de boom onder
home:een sleutel op demodus geven, zodat álles herbouwt. Dat is in #780 geprobeerd en teruggedraaid:
De deck-providers hangen aan het tabblad. Die boom afbreken disposet
DeckNotifierterwijl er nog naar geluisterd wordt — en erger dan de crash iswat eraan voorafgaat: dat is het niet-opgeslagen deck van de gebruiker. Dit kan
pas als de deckstaat boven die grens is getild, en dat is een aparte
verbouwing.
Wat er te kiezen valt
De regel uitrollen. Elk oppervlak dat een
AppTheme.*-getter leestkrijgt
AppearanceScope.modeOf(context), en een bronwacht dwingt dat af:een bestand dat een mode-afhankelijk token gebruikt in een widget-
buildmoet de modus lezen. Mechanisch, meetbaar, en het houdt de statische
getters intact — dus de export-isolate blijft werken. Nadeel: een regel
ruis per widget, en de wacht moet onderscheid maken tussen een
buildeneen hulpfunctie.
De tokens uit de statische laag halen voor alles wat chrome is, en
alleen de dia-tokens vast laten. Dat is de zuivere oplossing en de dure:
~200 gebruiksplekken, en de scheidslijn dia/chrome is precies wat #606 al
eens handmatig heeft moeten trekken.
De deckstaat boven het tabblad tillen en dan alsnog de sleutel op de
modus zetten. Lost het in één klap op voor élke widget, maar raakt de
provider-architectuur en de tabbladen.
Voorkeur van mij is 1: het is de enige die vandaag kan, en de bronwacht maakt
hem afdwingbaar in plaats van een goede gewoonte. 2 en 3 blijven daarna
mogelijk zonder dat 1 weggegooid hoeft te worden.
Hoe je het reproduceert
AppThemekleurt en niet meebeweegt.
Nagekeken vóór oppakken: dit kan nog niet.
lib/theme/appearance_scope.dartstaat niet opmain—grep -rn AppearanceScope lib/ test/op5db87945geeft nul treffers, entest/appearance_scope_test.dartentest/slide_quality_panel_contrast_test.dartbestaan daar evenmin.Het mechanisme waar alle drie de opties op leunen zit dus nog op de tak van #780 en is niet gemerged. Optie 1 uitrollen betekent nu: het zelf een tweede keer bouwen, naast een versie die al bestaat — precies de dubbele oplossing die een conflict wordt.
Niet geclaimd, geen
in-progress. Dit wacht op de merge van #780; daarna is het een mechanische ronde plus de bronwacht.De blokkade uit de vorige reactie is weg: #780 is gemerged (
ac997733), duslib/theme/appearance_scope.dartstaat op main en het mechanisme is er.Opgepakt. Tak:
fix/apptheme-statische-vlag-814.Eerst gemeten wat optie 1 werkelijk kost: 139 bestanden, 776 gebruiksplekken van een mode-afhankelijk
AppTheme-token. Dat is de omvang van de mechanische ronde. Voor ik daaraan begin kijk ik naar een route die niet in de drie hierboven stond — de elementenboom van de wortel af markeren alsneedsBuildzonder hem weg te gooien. Dat behoudt élkeState(dus geenDeckNotifier-dispose, dus geen verlies van het niet-opgeslagen deck) en laat toch elkebuildopnieuw lopen. Als dat werkt is het een reparatie van tientallen regels in plaats van 139 bestanden; als het niet werkt, is optie 1 er nog.Ik meld hier wat het wordt vóór ik het uitrol.
Gemerged in
266275db(PR #818), en op main geverifieerd —appearance_scope_testdraait daar groen.Eén ding hoort in het issue en niet alleen in de PR: de diagnose hierboven klopte niet. Ik schreef dat de scope zijn verandering niet meldt en dat elk oppervlak daarom een eigen aansluiting nodig had. De scope herbouwt wél; wat stopt is de laag eronder, want
Element.updateChildslaat een herbouw over zodra het nieuwe widget identiek is aan het oude — en tweeconst-instanties van hetzelfde zíjn identiek.Daardoor is optie 1 (139 bestanden, 776 plekken) niet nodig gebleken en is geen van de drie routes uit dit issue gevolgd. Wat het wel werd: bij een moduswissel élk element onder de scope als 'moet opnieuw bouwen' markeren zonder er een weg te gooien. Elke
buildloopt opnieuw, en géénStatesneuvelt — dat laatste is precies waarom het márkeren is en geen sleutel op de modus, die in #780 het niet-opgeslagen deck meenam.Netto is er meer weg dan bij: de aansluitregel in het kwaliteitspaneel, de bronwacht die hem afdwong,
modeOfen deInheritedWidgeteronder zijn allemaal geschrapt.En een waarschuwing voor wie hier later komt: de toets die met #780 meekwam kon deze bug per constructie niet vangen. Twee keer
pumpWidgetvervangt de wortel en herbouwt de hele boom, dus het blad kleurde 'vanzelf' goed. De nieuwe opstelling volgt de app — modus boven deMaterialApp, blad eronder achter eenconstkind — en wordt rood zodra de markering eruit gaat.