Skip to content

Configuration design

ALTaleX edited this page Oct 14, 2026 · 4 revisions

Configuration design principles

The editor has three main jobs: edit one configuration layer, capture reusable effective presets, and reliably undo its own preview changes. The repository's design contract is the detailed reference. Configuration and registry reference and Preset library and packages describe everyday use.

Editing and effective behavior are separate

A window edits HKLM by default, or the original interactive user's HKCU with --scope=hkcu. Ordinary controls show that layer's values or local defaults, never borrowed values from the other layer. A yellow warning identifies machine settings masked by the current user; an information icon identifies absent user settings inheriting from HKLM. Both remain editable. Windows color and transparency use the original-user destinations described below. Internal base/Override variants are not separate editing controls.

Runtime still resolves both layers. Ordinary values prefer HKCU; colorization uses HKCU Override, HKLM Override, HKCU base, HKLM base, then default. For ordinary configuration, Default means no customization in this layer, so it permits inheritance. It does not force the renderer's built-in default everywhere. The GUI's system-transparency mapping is an exception: preset Default writes EnableTransparency=1 instead of removing a value.

For valid values, 3.1.0 restores the order used before d6b4414 (2026-08-02). Builds from that commit through 3.0.2 preferred HKCU base over HKLM Override. The two colors and three balance pairs are affected; see the exact keys and rollback guidance. The ten managed color settings have additional GUI rules independent of runtime lookup.

Each operation has a clear boundary

Action Meaning
Ordinary edit Change only the selected layer, as a preview; Windows color and transparency use their separate rules below.
Apply preset Establish ordinary preset settings in the selected layer; HKLM application removes conflicting current-user values, while HKCU preserves HKLM. Ordinary defaults remove only target-layer customization; Windows color and transparency follow their separate rules.
New / Update Save effective configuration across both layers into a reusable preset. Requires no pending edits; it does not implicitly Save.
Merge Consolidate effective known configuration into the selected layer. Requires no pending edits and confirmation; remains reversible. HKLM merge cleans copied valid user values, HKCU merge preserves machine values.
Restore defaults Remove known OpenGlass customizations from this layer; another layer may still determine the result.
Save / Revert Save synchronizes AccentColorMenu and accepts the preview; Revert undoes this GUI's net changes. Neither modifies saved presets.

The bottom-left More menu normally contains Merge into HKLM/HKCU... and Restore defaults...; holding Shift while opening it also reveals Sync and the scope switch described below. Save and Revert remain visible on the right.

Sync reloads the editing layer's controls and notices, original-user Windows color state, preset library, transparency/power diagnostics and dwm.exe WER configuration. Sync requires a clean preview: pending configuration, Windows-color and resource changes, including pending recovery, must be saved or reverted first. The menu and action entry point enforce the same condition. Sync does not journal unrelated external changes and never saves or reverts implicitly. It does not write configuration, request an accent refresh or notify DWM. It is unavailable during a preview operation or shutdown. Preset enumeration retains the existing Refresh recovery/cleanup behavior; symbol-download progress and selected inputs remain unchanged.

Holding Shift while opening More also reveals Switch to HKCU/HKLM view. It requires no pending edits or symbol download and never implicitly saves or reverts. The replacement window keeps the original user identity, session editor lock, placement and selected tab; switching itself changes no configuration or accent color.

A clean startup and successful Revert qualify as having no pending edits; there is no requirement to click Save once unnecessarily. Apply and Restore defaults can be used during a preview. The checkpoint covers all layers actually changed, not whole registry directories. Failure restores the current attempt; Revert returns to the first checkpoint. Untouched external values survive. Normal close reverts; Esc belongs to the focused control.

A preset is scope-independent and preserves default, automatic and theme behavior. Applying it can combine with configuration from the other layer. The library therefore has no current-preset identity, matching or persistence. Selection only identifies the target of a library operation; it does not apply a preset. Save/Revert manage configuration changes and retained source notices independently of selection. Status reports only trust or load problems.

Accent color is the explicit exception

Color preference belongs to the original interactive user even when the editor targets HKLM. Color mode and manual RGB participate in preview rollback. Manual writes AutoColorization=0 and directly updates ColorizationColor/ColorizationAfterglow RGB and DWM AccentColor (0xFFBBGGRR), followed by a targeted ImmersiveColorSet notification; Automatic uses AutoColorization=1 and the synchronous forced shell request used by UpdateWallpaperTransition, then synchronizes DWM AccentColor from the resulting ColorizationColor RGB before notifying DWM. Save separately synchronizes AccentColorMenu from the current RGB, skipping equal values and ignoring color-selection policies. The GUI preserves the individual ColorizationColor/ColorizationAfterglow alpha values during direct RGB writes and does not intercept uxtheme color calls. Windows may still change companion state asynchronously. Strength is stored in the selected layer's GlassOpacity; Win7 writes the three balance Overrides internally. New presets capture only these Overrides, without falling back to base balances; schema 3 ignores base balance fields; schema 1/2 import and explicit Merge retain compatibility conversion to Overrides without changing the bases. GUI configuration writes leave those Windows base keys untouched. Advanced manual values remain supported without separate balance controls. In automatic mode, Custom follows the original user's current accent RGB through deferred, read-only refreshes on color/settings notifications and window reactivation. Read failures preserve the previous swatch. These refreshes do not change registry values, saved presets or the Save/Revert checkpoint.

The colors page has a multicolor Automatic swatch; fixed/custom swatches select manual coloring. Both color choices remove ColorizationColorOverride and ColorizationAfterglowOverride from original-user HKCU and HKLM, regardless of editing scope. ColorizationColor and ColorizationAfterglow always target the original user's HKCU, even for an HKLM preset target; neither layer should mask them. All four deletions are reversible configuration changes. New GUI presets never generate or apply these two Override settings; legacy entries are ignored. Only rollback may restore a value previously deleted by this GUI. This special cleanup does not apply to intensity or other ordinary edits. Clicking Automatic uses the native wallpaper-calculation alpha for selected-layer GlassOpacity and, in Win7 mode, the three balance Overrides, as part of the same preview. Balances use the original alpha byte directly; only GlassOpacity is rounded to a percentage. Preset application and Automatic refresh/recovery retain their own intensity settings. A saved preset with accent RGB selects manual mode; without RGB it selects automatic coloring and requests a wallpaper refresh. The Include accent color option starts checked when automatic coloring is off. This does not transfer an editing scope, private API structures or ongoing control of Windows coloring. Revert restores mode/manual RGB; Automatic restoration requests the current wallpaper color. Changed Accent and directly written DWM values have independent raw backups for Manual recovery. Missing AutoColorization means Manual and is restored as DWORD 0. Later Windows writes are not monitored or added to a deferred journal; Automatic recovery does not restore old derived RGB. Successful refresh delivery completes before a subsequent GUI manual choice; later external writes remain independent. The separate uxtheme patcher discussion is not an installation step or a dependency of this GUI workflow.

Native alpha and later wallpaper changes

Automatic selection combines the Shell's applied RGB with the native image algorithm's strength. The GUI obtains the latter through IDesktopWallpaperPrivate::ComputeImageColorizationColor after enabling Automatic, using the original user's COM identity even under alternate-credential elevation. A failed COM call rolls back the attempt. This changes neither preset format nor the Windows base color alpha.

In the inspected shell32 10.0.17763.737 and 10.0.26100.9549, successful image-color selection calculates:

rangeSum = sum(max(R, G, B) - min(R, G, B))
alpha = min(175, 125 + floor(rangeSum / pixelCount))

Windows caps each analysis dimension at 256 pixels. The sum covers pixels with nonzero image alpha, while pixelCount includes the whole analysis image area. Multiple images contribute their sums and counts before division. The legacy path unpremultiplies RGB first; 26100's feature-41486951 weighted-RGB path skips that step but uses the same alpha formula. The result describes colorization strength derived from RGB statistics.

The lower and upper bounds, 125 and 175, are hardcoded. An average channel difference of 50 already reaches 175, so different wallpapers can produce the same strength. The API can also return native fallback 0xC4FFFFFF (alpha 196), or reuse cached HKCU\Control Panel\Desktop\ImageColor during initialization. The bounds describe the normal calculation on those revisions, not every possible COM return or Windows build. OpenGlass keeps using the returned native alpha without substituting a fixed strength or adding a clamp.

GUI Automatic selection and the theme extension use the original alpha byte for Windows 7 balances, and round it separately for GlassOpacity. The shared conversion maps 175 -> 69% -> 176 if that percentage is later converted back to alpha. The extension getter preserves the stored byte when it already matches the effective percentage; otherwise it reconstructs alpha from GlassOpacity. A registry value of 176 alone therefore proves neither a fixed native alpha nor which writer rounded it.

The inspected shell32 10.0.26100.9549 drops native alpha when CDesktopBrowser::_SetDWMAndImmersiveColor converts ARGB to RGB. Reading the final ColorizationColor alpha cannot recover that original calculation. Later Shell-driven wallpaper changes still follow this path: RGB changes, while the last explicit OpenGlass GlassOpacity and balance Overrides remain. This known loss is a potential target for a community mod; OpenGlass does not require one or continuously rewrite strength. A mod that changes only Windows base values must also account for OpenGlass Override precedence. See the source contract.

Keep saved content simple and durable

The local library keeps one current directory per entry; ZIP is for transfer. A details ListView and context menus replace the button bank. External packages require Trust and import after validation and review; import never applies. Accepted content applies directly on double-click. Update replaces the selected entry and Export uses saved content. Delete removes library files while fixed Machine/original-SID resources keep current configuration and rollback independent. Eligible protected assets hard-link first, otherwise copy; published file contents and ACLs are never modified through shared links. Same-path resource changes participate in dirty/Revert and trigger Theme refresh. There is no Unsaved draft or permanent revision history.

Resources are captured and validated; known sources and attached terms are retained. Author with LICENSE identifies the declared rights holder; without LICENSE it is a reference source. Metadata is editable without import-based locking. The GUI does not certify authorship, ownership or license compatibility. New configuration/RGB/layout uses OpenGlass Attribution v1 and LICENSE covers images; legacy packages retain original scope. Storage details must not become extra configuration modes or user-facing ownership decisions.

The installer's optional completion-page launch uses runasoriginaluser, so the GUI starts under the installing interactive user's pre-UAC identity and performs its own authenticated elevation. Do not use runascurrentuser here: alternate administrator credentials would otherwise become the GUI's configuration user. If Setup was explicitly started already elevated, Inno Setup cannot recover a pre-elevation identity; launch the GUI from the intended user's desktop or Start menu instead.

Permissions and identity

The GUI still elevates at startup while retaining the original user's identity. Scope does not change permission requirements: administrative actions remain guarded and read-only diagnostics remain available. No configuration operation enumerates other users' hives or deletes Windows DWM state wholesale.

The transparency checkbox defaults to the original interactive user's Windows EnableTransparency setting, independent of editing layer and elevation identity. Missing/invalid values display as disabled, matching the runtime. Presets retain their ColorizationOpaqueBlend field: capture inverts the Windows boolean, with missing/invalid values captured as 1; application maps zero or Default to EnableTransparency=1 and nonzero to 0. The Windows value is never deleted. The package never contains EnableTransparency, and application leaves both DWM opaque-blend values untouched. Save/Revert and interrupted-operation recovery record the actual Windows value with its raw type, bytes and absence. Existing raw values are restored exactly; absence is restored as DWORD 0, including recovery records from earlier versions. --no-system-transparency restores the old checkbox behavior and ordinary DWM capture/application of ColorizationOpaqueBlend; the choice survives elevation and switching views. Merge and Restore defaults remain DWM configuration operations and preserve Windows transparency.

Why the GUI avoids SetUserColorPreference

The examined Windows 10.0.26100.9549 implementation has a serious cross-process race: it changes the accent palette before finishing preference publication and writes StartColorMenu and AccentColorMenu separately. Windows.UI.Immersive registry watchers can read mixed or stale preferences and then overwrite newer DWM colors through uxtheme. ProcMon captured both mixed reads and a complete old snapshot overwriting a successful new-color write; the callback stack confirmed the system synchronization path. Atomic shared-memory writes do not protect the complete operation, and a forced broadcast does not bypass the helper's same-preference write optimization.

Manual writes ColorizationColor/ColorizationAfterglow RGB and DWM AccentColor directly, followed by the targeted ImmersiveColorSet notification. It does not publish AccentColorMenu during preview, generate Start color, palette or history, or force a manual broadcast. Save synchronizes the current RGB to AccentColorMenu without consulting policy. Manual recovery also writes AutoColorization=0 when it was originally absent. This avoids repeated persistent-preference writes during preview, but cannot serialize other Windows processes or prevent later external writes.

The GUI does not call private DWM color Get/Set APIs. After a successful Automatic Shell request, it synchronizes DWM AccentColor from the resulting ColorizationColor RGB as opaque COLORREF before notifying DWM; equal values are skipped. AccentColorMenu is only observed to track actual Shell side effects for recovery, and GUI synchronization waits for Save. The uxtheme setter can skip DWM synchronization when its shared preference already matches, without comparing persistent Accent values; this mismatch alone does not prove a race. Manual rollback restores recorded raw values, while Automatic rollback recomputes current derived colors. See the core contract.

The GUI uses only WM_SETTINGCHANGE with the ImmersiveColorSet category for colorization notifications, sent directly to the DWM window with SendMessageTimeoutW and a one-second timeout. SendNotifyMessageW rejects this cross-process string message. Notifications carry no color snapshot; DWM reads the current registry state. Automatic's request to Explorer remains synchronous because its resulting RGB is needed before the following writes. Both OpenGlass architectures handle WM_SETTINGCHANGE with wParam=0 and the ImmersiveColorSet category by updating the OpenGlass backdrop, then forward the message to the native window procedure. Other WM_SETTINGCHANGE categories are forwarded without an OpenGlass update. WM_DWMCOLORIZATIONCOLORCHANGED retains the OpenGlass backdrop update for compatibility; theme-resource changes use WM_THEMECHANGED through SendNotifyMessageW and retain the OpenGlass theme update. GUI, engine and theme extension share the same UpdateType: Backdrop maps to colorization refresh and Theme maps to theme refresh. The notification helper sends colorization first when both flags are present. These handlers do not drain queued native messages. These remain best-effort notifications, not desktop-wide broadcasts or guarantees that rendering has completed; delivery failure does not keep otherwise completed recovery pending.

Color-selection policies

A valid PersonalColors_Background policy selects forced colors: Windows obtains its background/accent pair from PersonalColors_Background and PersonalColors_Accent rather than the user preference. NoChangingStartMenuBackground gates implicit preference refresh but does not stop all explicit setters. Skipping AccentColorMenu does not stop propagation of the forced colors; a later Windows refresh may replace DWM RGB with policy colors. Manual writes remain independent OpenGlass customization, while Automatic and its recovery follow the shell result, including policy overrides. See the core design contract for the distinction.

OpenGlassGUI does not consult color-selection policies when synchronizing AccentColorMenu. Only Save explicitly publishes the current original-user ColorizationColor RGB as an opaque COLORREF, skipping an equal value. Preview writes DWM colors directly; it does not synchronize AccentColorMenu. Policies themselves are never modified. This does not disable Windows policy processing: Automatic still follows the Shell result, and later Windows refreshes may apply forced colors.

Manual writes AutoColorization=0, updates original-user ColorizationColor and ColorizationAfterglow RGB while preserving each alpha, and writes DWM AccentColor as 0xFFBBGGRR. The two Colorization values must already be readable DWORDs; DWM AccentColor may be absent or have another type, which is backed up before replacement. All preview write targets must be writable before mutation. AccentColorMenu is not a Manual preview target, so preview does not require write access to it. Save checks its write access before publishing the current RGB.

AccentColorMenu is the persistent Windows preference. Save reads the original user's current ColorizationColor RGB and synchronizes this preference regardless of editing layer or policy. Compare its raw value with the requested opaque COLORREF and skip equal values without a write or rollback entry. The final write uses the existing preview transaction: its raw type, bytes or absence are recorded before mutation, and Save accepts the complete checkpoint only after success. Failure restores that Save attempt while retaining earlier previews; failed recovery remains retryable. No separate pending-color state is kept. Automatic Shell requests may themselves change AccentColorMenu before Save; record and reconcile those actual side effects for recovery without explicitly synchronizing the menu preference during preview. Untouched external values survive Revert. DWM AccentColor remains an independent Windows value with its own raw recovery, and Automatic recovery recomputes it from the Shell result.

NoChangingStartMenuBackground gates the normal cache/registry refresh branch used by GetImmersiveUserColorSetPreference; it does not prohibit explicit setters. The logon path can read the preference and invoke a setter separately. Save therefore publishes the current preference even when this flag is nonzero. Until Save, Windows can still consume the previous AccentColorMenu and overwrite preview RGB; direct DWM writes do not prevent later external or policy-driven updates.

In the inspected uxtheme 14393.0 and 26100.9549 implementations, a cached nonzero REG_DWORD from HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization\NoChangingStartMenuBackground prevents this getter branch from calling SetColorPreferenceHelper. Without that guard, eligible reloads can update DWM and conditionally broadcast WM_SETTINGCHANGE / ImmersiveColorSet; they do not call the exported SetUserColorPreference. Suppressing these broadcasts can reduce repeated GUI color-control refreshes and stutter, but does not stop watchers, explicit setters or other notifications. The policy-refresh function itself can broadcast after a successful change. It updates the cached flag only on a successful DWORD read, so deletion or a wrong type does not clear a previously cached flag even after a reread. OpenGlassGUI never sets this policy. See the core design contract for the call conditions and version limits.

Changing the forced-color policy during a desktop session can leave registry and process policy caches out of sync. The GUI does not read or refresh these policy caches and does not guarantee RGB persistence during that transition. Its Save-time AccentColorMenu synchronization is unconditional with respect to policy; Windows remains responsible for applying policy colors.

Clone this wiki locally