Windows 10 Night Light színhőmérséklet

Miután felfrissítettem a rendszerem a Creators update-tel és elolvastam az újdonságokat (megjegyzem van pár vicces), úgy döntöttem leváltom a f.lux-t az új Night Lightra. Működik is szépen, csakhogy láthatóan nem ugyanazt a színhőmérsékletet állította be a Microsoft alapértelmezetten, mint a f.lux. A probléma, hogy a csúszka mellett nem is jelenik meg a beállított színhőmérséklet, így a gyakorlatban a UI-ról esélyem sincs, hogy ugyanazt az értéket adjam meg.

Nem hagyott nyugodni a dolog, ezért kis nyomozás után a GitHubon találtam egy PowerShell kódot, ami a registryben állítgatja a Night Light beállításait*. Apró probléma, hogy a beállítások egy bináris struktúrában vannak tárolva, amiről nem találtam további információt**. Némi nyomozás után azonban azt is kiderítettem, hogy egész pontosan egy byte értéke érdekes, ez (nálam)

0x12

(legalacsonyabb színhőmérséklet) és

0x65

(legmagasabb színhőmérséklet) között változik. Az előbbi érték egy korábbi insider build bejelentése szerint 1200K-nek, utóbbi pedig a f.lux azonos (fehér) beállítása alapján 6500K-nek felel meg. Ha nem hexadecimális, hanem decimális számok lennének, pont jó lenne. :) Azért így is kiszámolható, hogy a f.luxban megszokott 3400K értékhez

0x2E

-t kell megadni lineáris skálát feltételezve.

Azt egy picit bonyolult elmagyarázni, hogy pontosan melyik byteot kell átírni, mivel a struktúra hossza a beállítások függvényében még változik is. Amit biztosan mondhatok, hogy a kérdéses byteot a

0xCF 0x28 0x??

bytesorozat előzi meg (értelemszerűen a

0x??

bármi lehet), utána pedig a

0xCA 0x32 0x0E

bytesorozat található. Ezt a fent linkelt PowerShell kód is alátámasztja. Persze az is lehet, hogy csak véletlenül ugyanazokat a beállításokat adta meg a script szerzője is, ezért más beállítások esetén a bytesorozatok eltérhetnek.

* a

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$$windows.data.bluelightreduction.settings\Current

kulcs alatt a

Data

értékről van szó

** a Night Light a

%SYSTEM32%\Windows.Shell.BlueLightReduction.dll

-ben van implementálva, de ezt inkább nem akartam visszafejteni

Hozzászólások

Ez menyire gusztustalan mód a beállítások tárolására! Fájt volna rendes registry értékeket használni? Bár ahogy a környékét elnéztem, ez valami új divat. Brrr.

Üdv,
Marci

>> de ezt inkább nem akartam visszafejteni

:(

>> menyire gusztustalan mód a beállítások tárolására!

az említett kulcs alatt microsoft bonddal szerializált Windows.Data.BlueLightReduction.Settings struktúrát találsz compactbinary (ProtocolType.COMPACT_PROTOCOL, 0x4243, lásd a kulcsban 0x10-nél) formában

>> Amit biztosan mondhatok, hogy a kérdéses byteot a 0xCF 0x28 0x?? bytesorozat előzi meg
>> Azt egy picit bonyolult elmagyarázni, hogy pontosan melyik byteot kell átírni

a Windows.Data.BlueLightReduction.Settings elemei (automaticOnSchedule, automaticOnSunset, targetColorTemperature, manualScheduleBlueLightReductionOnTime, manualScheduleBlueLightReductionOffTime, sunsetTime,...) közül jól szúrtad ki a 40-es (0x28) field azonosítójú int16 típusút (targetColorTemperature):

0xCF 0x28 (1100111100101000) < ez a bond field id és típus ebben az esetben 2 byteon ábrázolva 110tttttiiiiiiii formában, ahol t bitjei 0x0f = BondDataType.BT_INT16-ot adnak, az id pedig az előbb említett 40 (0x28) - az érték tehát nem 1 byteon lesz ábrázolva, hanem kettőn

>> (értelemszerűen a 0x?? bármi lehet)

bizonyos megkötésekkel

>> utána pedig a 0xCA 0x32 0x0E bytesorozat található

esetleg más field, (0xCA egyábként BondDataType.BT_STRUCT típusd ad ha jól tévedek), vagy éppen BT_STOP lezáró
egyszerűbb és biztosabb a 40-es id-re koncentrálni

>> egész pontosan egy byte értéke érdekes, ez (nálam) 0x12 (legalacsonyabb színhőmérséklet) és 0x65 (legmagasabb színhőmérséklet) között változik. Az előbbi érték egy korábbi insider build bejelentése szerint 1200K-nek, utóbbi pedig a f.lux azonos (fehér) beállítása alapján 6500K-nek felel meg. Ha nem hexadecimális, hanem decimális számok lennének, pont jó lenne. :)

az int16 típusú targetColorTemperature érték két byteon tárolódik, a gui segítségével ez (0xE0, 0x12) és (0xC8, 0x65) között állítható

az int16 értékek compactbinary szerializáció esetén zig-zag enkódolva tárolódnak 1hhhhhhh0lllllll formában, ahol csak a h ill. l jelölésű bitek értékesek, esetünkben:

0xC8 0x65 ([1]1001000 [0]1100101) -> 11001011001000 (= 0x32C8 = 13000)
0xE0 0x12 ([1]1100000 [0]0010010) -> 00100101100000 (= 0x0960 = 2400)

zig-zag dekódolva pedig:
dezigzag(13000) = 6500, illetve
dezigzag(2400) = 1200

Wow, kiváló leírás, köszönöm!

Sajnos a Microsoft Bondról még nem hallottam korábban, és ahogy nézem erre az se indok, hogy amúgy a Windows programozáshoz nem értek...

Arra én is gondoltam, hogy 16 bites számról lehet szó, csak sehogy nem jöttek ki értelmes számok. A ZigZag kódolás bennem fel se merült, soha nem használtam még ezt a kódolást. Így valóban értelmesebbek a kapott számok. :)

>> a f.luxban megszokott 3400K értékhez 0x2E-t kell megadni

a fentiek alapján (0x90, 0x35)-öt