
En CSS-variabel, fem granskningsrundor och en Swift-verktygskedja som ljög
GeekBye v2.0.7 gjorde hela overlayn justerbart genomskinlig — vilket låter som en enda rad CSS men absolut inte var det. Den verkliga historien är vad kodgranskningen fångade: två ytor som vägrade tona bort, en inspelningsrad som såg fel ut vid samma opacitet, och en kompilerad binär som fladdrade 672 byte fram och tillbaka eftersom vår egen dokumentation gav en granskare fel Swift-version.
"Gör overlayn genomskinlig" är den sortens uppgift som låter som ett reglage och en CSS-opacity-egenskap. GeekBye v2.0.7 levererade exakt det användaren ser — ett enda justerbart "ljust läge" som låter dig se igenom assistentens paneler ner till vad som än finns bakom dem. Men det intressanta med den här releasen är inte funktionen. Det är de fem granskningsrundor det tog att få den rätt, och en krigshistoria om en kompilerad binär som ändrade storlek eftersom vår egen dokumentation ljög för en granskare.
Det rätta sättet att göra ett helt gränssnitt genomskinligt
Den naiva versionen av det här är att strö ut ett opacitetsvärde över varje panelkomponent och kalla det klart. Det är en underhållsfälla: ett dussin hårdkodade värden som glider isär i samma stund någon rör vid ett av dem.
I stället använder v2.0.7 ett delat CSS-verktyg och en token per yta. Det finns en enda overlay-surface-klass som beräknar en panels bakgrund från två custom properties: en bas-opacitet som varje yta deklarerar för sig själv (kontrollraden, chatten, transkriptbubblorna, kodblocken och så vidare väljer var och en sin egen), och en global alfamultiplikator som ligger på overlayns rot och representerar användarens reglageinställning. Varje yta läser samma multiplikator; var och en behåller sin egen karaktär. Avgörande nog är det bara panelbakgrunden som skalas — text, ikoner och backdrop-blur förblir fullt renderade, så "genomskinlig" betyder aldrig "oläslig".
Två beslut i den designen är värda att lyfta fram, eftersom de är skillnaden mellan en funktion som hjälper och en som genererar supportärenden:
- Standardvärdet är helt ogenomskinligt. Opacitetsinställningen levereras på 100 % — en no-op. Ingens overlay blev plötsligt genomskinlig vid uppdatering; genomskinligheten finns där när du sträcker dig efter den och är osynlig tills dess.
- Inställningen valideras defensivt. Det finns en enda sanningskälla för min, max, standard och steg, plus en normaliserare som skyddar mot det tomma/saknade fallet. Det spelar roll på grund av en JavaScript-fotpistol:
Number(null)är0, så en saknad inställning som naivt tvingas om skulle snäppa overlayn till dess mest genomskinliga läge i stället för dess standard. Normaliseraren fångar det innan det kan hända.
Dra i reglaget så färgas hela overlayn om live, mitt i en inspelning, eftersom varje yta prenumererar på samma inställning. Ingen omstart, ingen omladdning.
Vad granskningen fångade (och som ett test på en enda skärm aldrig skulle ha gjort)
Här slutade "en CSS-variabel" vara enkelt. Tre buggar dök upp i granskningen, och två av dem är samma läxa i olika förklädnader.
En panel som inte ville tona bort. Overlayn för tangentbordsgenvägar förblev envist solid medan allt annat blev genomskinligt. Orsaken: den renderas utanför det DOM-underträd som bär opacitetsvariabeln, så den ärvde aldrig värdet som kaskadade ner från overlayns rot. CSS custom properties ärvs genom DOM-trädet — och om en nod inte faktiskt är en ättling till där du sätter variabeln får den tyst ingenting. Fixen var att sätta variabeln lokalt på den panelen också.
En hover-ton som försvann. Fn/Assist-knapparna tappade sitt cyanfärgade hover-sken. Genomskinlighetsverktyget satte bakgrunden med !important (det måste vinna över ytornas standardvärden), och det körde över hover:-bakgrundstonen på samma element. Specificitetskrock. Fixen var att göra hover-tonen lika eftertrycklig så att den kunde vinna tillbaka vid hover.
Båda dessa är samma underliggande sanning: en CSS-variabelkaskad är en verklig korrekthetsgräns, inte en stildetalj. Arv och specificitet avgör om ditt värde ens når elementet, och ingetdera syns i en skärmdump förrän det är fel.
Samma opacitet, olika utseende. Den mest subtila: inspelningsraden och vilolägesraden var satta till identisk basopacitet, och såg ändå synligt olika ut. Varför? Inspelningspillret använde en tyngre backdrop-blur, och en stark oskärpa över en mörk bakgrund medelvärdesbildar mot ett mörkare resultat — så lika alfa gav olika utseende. Den hade också en svag kant där vilolägesraden hade en ljus gradientringkant. Fixen matchade oskärpenivån och ringen. Läxan fastnade: lika alfa är inte lika utseende när oskärpa kommer in i bilden. Genomskinlighet är ett system av samverkande effekter, inte ett enda tal.
Binären som ändrade storlek eftersom dokumentationen ljög
Nu krigshistorien, och det är min favoritsort — den där verktygen och dokumentationen är oense och en noggrann granskare hamnar i skottlinjen.
GeekBye levererar några förkompilerade Swift-binärer (native-hjälpare för saker som mötesdetektering). Eftersom en kompilerad binär är incheckad i repot måste varje utvecklare kompilera den med exakt samma Swift-version — olika verktygskedjor producerar olika byte från identisk källkod, och det skulle betyda en spökaktig git-konflikt varje gång någon bygger om. Så det finns ett skript som upprätthåller en specifik version: Swift 6.3.x, kontrollerad vid byggtillfället.
Under granskningen av den här releasen flaggade en granskare att en binär borde byggas om för att matcha "repots påbjudna verktygskedja". Utvecklaren gjorde precis det — och binärens storlek ändrades från 89,184 byte till 88,512. Commit-meddelandet sa till och med att det "återställde byte-stabil utdata" genom att bygga om med Swift 6.2.1, "repots påbjudna verktygskedja".
Fast 6.2.1 var fel version. Byggkontrollskriptet krävde 6.3.x. Problemet var att prosa-dokumentationen — README och bidragsguiden — fortfarande sa 6.2.1 på ett par ställen. Så en samvetsgrann granskare och en samvetsgrann utvecklare, båda med målet att göra rätt, följde dokumentationen rakt in i att checka in precis den artefakt som kontrollskriptet finns till för att avvisa. En 6.2.1-binär i ett 6.3.x-repo är exakt den drift som skulle förstöra varje annan utvecklares rena ombyggnad.
Nästa commit fixade det — och fixen är poängen. Den byggde inte bara om binären till dess 6.3.x-form (storleken återställd till 89,184, tillbaka precis där den började). Den rättade också de föråldrade "6.2.1"-referenserna i dokumentationen så att fällan inte kunde gillra igen. Binären fladdrade 672 byte och tillbaka över två commits, och den verkliga buggen var aldrig binären. Det var att två sanningskällor — kontrollskriptet och den skrivna dokumentationen — var oense, och en människa litade på fel.
Tre saker den här releasen lärde ut
- En CSS-variabelkaskad är en korrekthetsgräns. Två av tre granskningsbuggar handlade om en variabel som inte ärvdes och ett
!importantsom körde över ett hover-tillstånd. Om ett värde måste nå ett element genom arv eller vinna genom specificitet, så är den vägen logik — verifiera den som logik, inte som stil. - Lika parametrar kan ge olika resultat. Inspelningsraden och vilolägesraden delade en opacitet och såg ändå olika ut eftersom en annan oskärpa ändrade utfallet. När du enar ett visuellt system på ett tal, kontrollera att de andra variablerna runt varje yta inte tyst ändrar vad det talet betyder.
- När dokumentation och kontroll är oense, fixa oenigheten — inte bara symtomet. Buggen var inte en dålig binär; det var en dokumentation som angav fel verktygskedja och ett kontrollskript som sa något annat. Att bygga om binären behandlar symtomet. Att få varje sanningskälla att stämma överens är den verkliga fixen, eftersom nästa granskare också kommer att lita på dokumentationen.
GeekBye v2.0.7 levererade den enhetliga genomskinligheten, alla gränsfall granskade och verktygskedjans dokumentation rätad. Det är den sista av "tyst hantverk"-releaserna före tillförlitlighetssprinten som följde. För grunden under den, se vad en version 2 faktiskt kräver (v2.0.0); för den systerpolerade releasen, lugn mjukvara: flimmerfixen och svarslägeschippet (v2.0.3 + v2.0.5); och för hur overlayn förblir dold under ett samtal, hur man förblir osynlig under skärmdelning.