-
Notifications
You must be signed in to change notification settings - Fork 41
migration os settings app
github-actions[bot] edited this page Sep 2, 2026
·
1 revision
The Preferences window (desktop-mode-os-settings) is an App Framework app now: apps/os-settings/os-settings.os.php declares the window, os-settings.os.ts paints every page as a client view, and the sheet rides the app as a first-open companion style. The window id, wp.os.openOsSettings(), wp.os.registerSettingsTab(), the settings REST route, the user meta key and every settings key are unchanged. Read this if you reached into the panel's bundle, its stylesheet handle, or its config key.
| Before | Now |
|---|---|
The lazy os-settings-panel[.min].js bundle, <script>-injected on first open |
The app's client view, assets/js/apps/os-settings[.min].js, loaded with the window like every other app |
openStationConfig.osSettingsPanelBundleUrl |
Removed. The window's script is a companion of its registration. |
The os-settings stylesheet handle (assets/css/os-settings.css, deferred through openstation_deferred_styles) |
apps/os-settings/os-settings.css, injected on the window's first open by the framework. A plugin that appended selectors after the os-settings handle should depend on the app's handle, openstation-app-desktop-mode-os-settings, or ship its own sheet. |
src/settings/panel.ts, src/settings/sections/*, the section-builder SettingsCtx
|
Internal, and gone. Third-party code never had a supported import of them. |
The desktop window opened from desktop.ts with an inline render callback |
Registered by PHP; wp.os.openOsSettings( { tabId } ) still opens or focuses it, passing the page as the open-time tab param and switching a live window through wp.os.apps.local(). |
-
wp.os.updateOsSettings( patch )accepts everyOsSettingsStatekey. The write used to honour a hand-kept whitelist that leftcustomAccent,customGradient,customImage,wallpaperSettings,libraryHdOnly,heartbeatRate,showDesktopOnWallpaperClick,confirmCloseAllWindows,mioEnabledandmioStylereachable only from inside the panel. Every key now goes through the same sanitizer that reads user meta, with the current value as the fallback, so an invalid field is ignored rather than reset. The one exception stays:appliedThemeRecommendations, the seeded-theme ledger, is shell-owned and ignored. -
Activating a theme through
updateOsSettings( { desktopTheme } )seeds its recommended settings once, the first time the user wears it — what the Themes tab always did, and what the documented recipe silently skipped.wp.os.desktopThemes.applyRecommendedOsSettings()remains the deliberate re-apply. -
wp.os.resetOsSettings()is new — the window's Reset button as an API call. The uploaded image survives. -
wp.os.getOsSettings()returns the whole state.OsSettingsSnapshotis now an alias ofOsSettingsState(src/settings/types.ts); every key that was on the snapshot still is, with the ten above added. -
A settings tab's
render( body, ctx )runs once per registration, not on every panel repaint: the host element survives the app's diffing renderer. A tab that re-registers itself (or is re-registered by a live plugin refresh) paints again. Thectxit receives is unchanged.
-
$os->refresh_menu()is a new effect: one menu-payload refresh after the response lands, for an action that changed what the server registers. The Extended Options action uses it, and it is the framework's form of the rule in AGENTS.md ("a setting that gates a server-side registration must spend a menu refresh when it saves"). -
App::prefetch()computesdata()once at registration and ships it with the window config, so a client view paints from the declared state the moment the window opens instead of behind a spinner for the length of themountround trip — the beat in which the Preferences window's first click used to be lost. Opt-in; the app uses it because itsdata()is a handful of capability checks and options. -
focus/blurlifecycle actions fire on transitions. The shell reports a focus request on every pointerdown inside a window; the runtime now gates those, so a declaredfocushandler costs one round trip per return to the window rather than one per click. -
The runtime asks the shell for an undefined
<os-*>tag once per session, not on every repaint (the Components tab's warner demo renders two such tags on purpose). -
wp.os.registerNamespace()now reaches the livewp.osobject. It used to write onto the facade literal only, which is whywp.os.apps— the app runtime's own namespace — never existed on the page.
This wiki is generated from the docs/ directory — edits made here are overwritten by the next sync.
To change a page, open a pull request against docs/.
Guides
- Development guide
- Releasing openstation
- Agents security model
- API Index
- The App Framework — a window in one PHP file
- Architecture
- Bridge protocol — wiring overview
- <os-*> component reference
- Data model — where OpenStation keeps its data
- Native Desktop Host — Experimental
- Desktop themes
- Dock customization — two registries, one mental model
- The event-driven framework
- Files on the Desktop
- Folder sharing
- Getting Started
- Hooks Reference
- Icons
- JavaScript Reference
- The Living Tree — algorithm definition
- Window-scoped MIO
- Mio
- Mobile — the phone layer
- Multisite
- Native Windows & Framework Interop
- OpenStation Network
- Plugin compatibility layer
- Progressive Web App (PWA)
- Station Home
- Using openstation from your own plugin
- Workspaces
Migration notes
- Migration: built-in activity channels move to the os/ namespace
- Migration — Code Blue becomes an App Framework app
- Migration: window, wallpaper and widget bundles load on demand
- Migration — Posts, Pages, Users, User Edit, Plugins and Comments become App Framework apps
- Migration — the navigation model
- Migration — OpenStation Preferences becomes an App Framework app
- Performance settings move to Extended options
- Presence storage migration
- Migration — the Recycle Bin becomes an App Framework app
- Migration — the shell boots from its own screen
- Migration — Station Home becomes an App Framework app
- Migration: a native window's tabs move to the window chrome
- Migration — WP Explorer becomes the my-wordpress app
- Migration — WordPress package globals are no longer ambient
More
All examples
- AI Agents — extend and invoke from a plugin
- wp.os.ai.ask() — programmatic AI Copilot
- Tune the AI model config
- Custom arrange-menu action
- Open a child window its owner can't cover
- Style a specific admin page inside the iframe
- Code Blue — register your plugin's log file
- Open a file in the Code editor (deep-link from any window)
- Connect to a window — title-bar button + iframe pub/sub
- Content changes — live-refresh every window listing your type
- Custom window chrome (Experimental)
- Register a custom unfocused-window effect
- Example: render a data table
- Real file storage — react to uploads, gate policy, share from PHP
- React to a window being set free onto the real desktop
- Cross-window devtools — instrumentation primitives
- Add a dock item with a badge
- Decorate the dock without forking the renderer
- Replace the dock rail entirely
- Retune the Drafts widget's AI writing assistant
- Gate OpenStation by role
- Iframe-initiated window opens
- Build a feed reader without the bookkeeping
- Inject data into openStationConfig
- Render a list without losing clicks — renderKeyedList()
- Example: layout primitives (body → panel → row → col)
- Use <os-*> components from a plugin that ships as a zip
- Restyle and drive Mio
- Repairable form edits with MIO
- Register a window companion
- Pin your app to the phone tab bar, and react to the mode
- Add an action that works on a whole selection
- WP Explorer — custom post types and their folder
- WP Explorer — add a column to the list view
- Add an action button to a WP Explorer preview pane
- Example: native Posts window
- Example: native window with tabs
- Native windows
- Customize note → post conversion
- Send a notification
- OAuth relay — connect to an external service
- Ship a window as an .os.php app
- OS-file drop
- <os-flyout> — window-scoped sliding card
- Plugins window — extras
- Track who's around — wp.os.presence
- Example: progress bar
- PWA install — surface your own button
- React to window events
- Example: extend the Trash
- Register a slash-command
- Register a desktop theme from a plugin
- Register a game
- Example: register a desktop icon (Jorvy)
- Register a wallpaper
- Register a widget
- Related entities — extend the title bar's "Related" menu
- The native-window render ctx
- Revisions in their own window — extend or redirect "View revisions"
- Programmatic folder sharing
- Share state across multi-bundle plugins — wp.os.createSharedStore()
- Example: loading spinner
- Add an opt-in card to Station Home
- Observe stored-file cleanup failures
- Accept drops on your desktop icon
- Give a tile two icons, one per state
- Add a row to a window's ⋯ menu
- Example: window activity & the status ring
- Window controls
- Subscribe to window lifecycle events
- Window links — relate windows and restyle the ties (Experimental)
- Window loading state — spinner overlay & ready signal
- Show a banner at the top of a window
- Pulse a window's icon — Window.requestAttention()
- Register a custom window reveal
- Window slots
- Window themes
- Native window with bundle-bound config
- Place something where the user can reach it — wp.os.workArea
- Ship a workspace template