Let a desktop theme recommend OS settings - #434
Merged
Conversation
Adds an optional `recommendedOsSettings` block to the desktop-theme manifest (`dockSize`, `desktopLayout`, `windowRadius`, `dockRailRenderer`), sanitized against a filterable allow-list of presentation keys and exposed through the payload and the public desktop-theme API. Recommendations are seeded into a user's own OS Settings once, the first time they activate the theme, and never re-asserted; the ledger lives in `appliedThemeRecommendations`. OS Settings -> Themes gains an "Apply recommended layout" action for going back to the author's arrangement on purpose. `manifestVersion` now accepts 1 or 2. v1 manifests are unchanged, and a v1 manifest carrying the block still has it honoured. Also closes a pre-existing gap in `updateOsSettings`: `desktopTheme`, `unfocusEffect` and `windowRadius` were documented or snapshot-exposed with no writer, and presentation patches persisted without applying.
A desktop theme that declares `--desktop-mode-window-radius` in its tokens beats the Window corners preset: the compiled rule matches the shell root, while the preset is an inline style on `:root` that only reaches windows by inheritance. The theme winning is intended; the picker sitting there looking operable and doing nothing was not. The control now disables itself while a theme owns the token and names the theme, pointing at System default. It re-enables live when the theme is deactivated -- no Settings reopen. `<wpd-segmented>` gains a `disabled` prop for this, which also refuses picks rather than relying on pointer-events alone.
This reverts commit 31e219d.
Applying a theme's recommended layout moves the dock and the layout
under the user's cursor. That movement is the feedback -- a notice on
top of a visible change is noise, so both are gone: the one after the
first-activation seed and the one after the button.
The button now names the theme it belongs to ("Apply Neon Glass's
recommended layout") and does exactly one thing: set the settings.
Semantics are unchanged and match the spec: seeded once on first
activation, never on page load, never over a later user change, with
the button as the only path to a second application.
apply() wrote --desktop-mode-window-radius only as an inline style on :root, which reaches windows by INHERITANCE. A desktop theme that declares the same token gets it compiled onto `.desktop-mode-shell[data-desktop-mode-desktop-theme="..."]` and `body.desktop-mode-desktop-theme-...`, both of which MATCH an ancestor of every window -- so the theme won and clicking Sharp / Default / Round did nothing at all for as long as that theme was worn. The preset now also writes the property inline on the shell element. Inline outranks any selector, so the user's corner choice is authoritative. A theme that wants a particular radius asks through `recommendedOsSettings.windowRadius`, which sets the preference once and leaves it theirs. The bundled Neon Glass theme moves its 12px token to a `round` recommendation accordingly. Note its WINDOW_FRAME is a border-image, and CSS does not clip a border-image to border-radius -- while that frame is painted the artwork corners stay put whatever the preset says.
The two behaviours a theme author will actually hit while iterating: a recommended corner preset lands, and a key added in a theme UPDATE reaches nobody who already activated it -- the button is the way in.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an optional
recommendedOsSettingsblock to the desktop-theme manifest, so a theme's intended arrangement travels with it instead of living in a setup guide.{ "manifestVersion": 2, "recommendedOsSettings": { "dockSize": "large", "desktopLayout": "unified" } }The contract: applied once, the first time a user activates the theme — never on page load, never over a change the user made afterwards. A per-user ledger (
appliedThemeRecommendations) records which themes have been seeded, so re-picking a theme you've already worn changes nothing. OS Settings → Themes gains an Apply recommended layout button — the only path that applies a recommendation a second time.Allow-list. Four presentation keys only (
dockSize,desktopLayout,windowRadius,dockRailRenderer), filterable viadesktop_mode_desktop_theme_recommended_os_settings_schema. The enums reference the existingDESKTOP_MODE_OS_SETTINGS_*constants so they can't drift.dockRailRendereris checked twice — charset in PHP, registry membership in the shell at apply time — so an id nothing answers to is skipped rather than written into user meta. The shell only writes a key that already exists and already holds a string, so a manifest can't introduce a setting or flip a feature toggle.Back-compat.
manifestVersionnow accepts 1 or 2. v1 manifests sanitize exactly as before, and a v1 manifest carrying the block still has it honoured — dropping a valid, sanitized field over a version number would contradict the drop-and-continue rule the rest of the sanitizer follows. Themes installed before this feature shape to an empty set, not a missing key.Also in here (flagged separately, kept in this PR by request):
updateOsSettingshad no writer fordesktopThemeorunfocusEffectdespite the docs showing them, and nowindowRadiuson the snapshot at all. All three are wired up, and presentation patches now run the apply pass — previously they persisted but changed nothing until the next page load, which is why the docs had to pairupdateOsSettings({ desktopTheme })with asetActive()call.Docs updated in the same change:
desktop-themes.md,hooks-reference.md,javascript-reference.md,api-index.md,examples/register-desktop-theme.md.Testing
desktopThemesRecommendedOsSettings.php(schema, sanitizer, manifest integration, v1 back-compat, code registration, payload re-sanitization), plus ledger cases and a v2-accepted case.desktop-themes-recommended.test.tsandapi-update-os-settings.test.ts.typecheck,lint,buildclean.Manual: activate a theme with the block → dock/layout move once, with a notice. Change the dock size, re-pick the theme → your choice holds. Hit Apply recommended layout → the author's arrangement comes back. The reference
neon-glasstheme ZIP ships the block and its README explains the once-only contract.Theme:
neon-glass.zip