Prefs
Prefs holds MixOS's preference editors in one window: an expandable tree on the left, the selected section on the right. Appearance contains Themes, Fonts, Wallpapers and Terminal; Applications contains MixOS Desktop, MixOS Server and Creative; App Settings contains Email. The sidebar can be resized. The name is a nod to the Prefs drawer of AmigaOS, where each setting had its own small editor.
Applications
Each Applications section shows its followed apps, from the releases service: each app's installed version, the latest release, when it was published, and its status (up to date, update available, not installed, not checked, or check failed).
- Check for updates (Ctrl+Shift+R) asks GitHub about every followed app.
- Update group installs newer releases for installed apps in the selected group.
- Select an app to see its latest release notes, then:
- Install or update (Ctrl+I) installs it, or updates it if it is installed;
- Roll back returns to the previous version;
- Remove… asks first; Cancel is the default, so Enter never removes.
- Refresh (Ctrl+R) reads the list again without asking GitHub.
MixOS's mixos-desktop and mixos-server catalogue entries have their own
sections. A catalogue entry's optional category selects mixos-desktop,
mixos-server, creative or other; application names and publishers remain
catalogue data. The catalogue's top-level categories map can label a group,
for example categories: {creative: "Graphics"}.
Unrecognised catalogue entries remain accessible under an additional Other
section. Changing groups clears the previous selection and its release notes;
selecting an app through the Bus opens its group automatically.
One operation runs at a time; the status bar says what is happening and how it ended. Installs are per user, verified against the checksums each release publishes, and the previous version is kept for rolling back: see Application releases.
If the releases service is not running, the editor says so instead of an
empty list. You follow apps by listing them in
~/.config/mixos/releases.mx.
Appearance
Appearance → Themes sets the session's look through the settings service (settingsd): the colour scheme (each shown with its accent), the style (the scheme's own, or Plain, Pro, Studio or Classic), light or dark, contrast, and the window frame: a title bar drawn by the app or by the system, and which side the app's window buttons sit on.
Each change applies to the whole session as you make it, as in GNOME's settings: the apps that follow the session look (Prefs itself, BusViewer, and the portal's clients) change with it. Only the setting you changed is written. Changes made quickly one after another are sent in turn, never lost.
If settingsd refuses a change, Prefs keeps it and says so: Apply (Ctrl+S) tries again and Revert drops it. If the appearance is changed elsewhere at the same moment (another window, or an agent), Prefs follows it on every setting you did not touch. If it changed one you did, Prefs names it and applies nothing until you choose Keep my changes or Revert. Every change is checked against the revision you were shown, so it never lands on a change you have not seen. If its answer is lost, Prefs asks settingsd for the change's receipt before anything else is applied (Check again asks now); if settingsd no longer holds one, the session's current state decides what the status line says.
Appearance → Fonts shows the interface, heading and monospace faces currently installed on the window, with previews. Font family and size selection is not available yet; these faces follow the session design.
Appearance → Terminal holds the terminal's font, layout, cursor, focus ring, mouse and environment settings, plus Reset terminal. Each change uses settingsd and applies as it is made. Themes contains only the session theme controls. See the terminal settings for the defaults and ranges.
App Settings → Email
App Settings holds settings that belong to one application, kept in
the settings service like the session's look. It is separate from
Applications, which installs apps. Its first section is Email, the
email app's accounts and mail options (email.* in
settingsd; see the email settings).
- Accounts lists the accounts in the order Email's folder tree shows them, marking the default and any that are disabled. Add account opens a blank form; Move up and Move down reorder; Make default picks the account new mail is sent from (with none, the first enabled account); Remove… asks first, and Cancel is the default.
- The selected account's form holds its name, JMAP URL (https, no trailing slash), login email, an optional CA bundle (an absolute PEM path; blank trusts the system roots) and a signature. Typing stays in the form until Save; Revert drops it. Each field is checked by the settings service's own rules first, and a field it would refuse is named under the field and nothing is sent. Enabled applies at once.
- Mail holds messages per page (10 to 500), marking messages read when opened, and asking before deleting them; each applies at once. Reset email settings… asks first, then puts every email setting back to its default, which means no accounts.
Each change is one write to settingsd carrying the whole account list, and the default account in the same write when the change touches it (removing the default account clears it). Every write is checked against the revision shown, as on the Appearance panel. If settingsd refuses one, the status line gives its reason and the panel keeps showing what settingsd holds; your typing stays in the form.
Passwords never go to the settings service, whose settings every Bus
client can read, and Prefs neither keeps nor shows them. Set password
hands the typed password to Email itself (email.account.password.set),
which keeps it in its own private file, and empties the field; the field
gets the password back only if Email refuses it. If Email is not running,
Prefs starts it (apps.launch) and waits up to about 16 seconds for it to
come onto the Bus. Under the field, Prefs says whether Email holds a
password for the account, as Email reports it (email.accounts), or that
this is unknown because Email is not running. Connect now asks Email
to connect the account (email.account.connect). Forget password…
asks first (Cancel is the default), then has Email delete the password it
keeps; it is the only time Prefs sends an empty password, and it starts
Email if needed, as Set password does. Remove… goes through Email
when it may be running (email.account.remove): Email removes the account
from settingsd and forgets its password itself, and refuses while the
account is still being migrated from its old configuration
(MIGRATION_PENDING, shown as Email gives it). When Email is not running,
Prefs removes the account from settingsd directly and, once settingsd shows
it gone, asks a running Email to forget the password; Prefs does not start
Email for this, and if Email is away or refuses, the status line says the
password may still be held. An account still being migrated comes back
when Email next starts, by design.
An Email too old to know these verbs is reported as such, not retried.
-- What Prefs shows: accounts (with has_password), default, mail options.
send prefs prefs.email
-- Add an account; the answer carries its new id.
send prefs prefs.email.set body='{"op":"add","name":"Work","url":"https://mail.example.com","email":"admin@example.com"}'
-- Change one field, make it the default, move it, disable it.
send prefs prefs.email.set body='{"op":"update","id":"acct-0f3a2b1c9d8e","signature":"-- Admin"}'
send prefs prefs.email.set body='{"op":"default","id":"acct-0f3a2b1c9d8e"}'
send prefs prefs.email.set body='{"op":"move","id":"acct-0f3a2b1c9d8e","direction":"up"}'
send prefs prefs.email.set body='{"op":"enable","id":"acct-0f3a2b1c9d8e","enabled":false}'
-- A mail option.
send prefs prefs.email.set body='{"path":"email.mail.page_size","value":50}'
-- Hand a password to Email (answered once Email has), or forget it.
send prefs prefs.email.password body='{"id":"acct-0f3a2b1c9d8e","password":"…"}'
send prefs prefs.email.password body='{"id":"acct-0f3a2b1c9d8e","forget":true}'
prefs.email.set takes op add, update, remove, move, default
or enable, or path and value for a mail option. Over the Bus,
remove removes at once: the confirmation belongs to the window. A field
the settings service would refuse is answered with ARGUMENT, naming it.
For scripts that do not need Prefs open, call settings.apply on the
email.* paths directly, and email.account.password.set on Email.
For agents
Prefs answers on the Bus as prefs. prefs.info reports the whole state;
prefs.apps the rows, selection and notes; prefs.appearance the session
look, the expected look while a change settles, any held or conflicting
edits and the revision read; prefs.appearance.set
changes it at once (scheme, style with own for the scheme's own, mode,
contrast, decorations, caption_side); prefs.select {app} and
prefs.section {name} selects themes, fonts, wallpapers, terminal, mixos-desktop,
mixos-server, creative, other or email and expands its parent. prefs.panel {name}
remains compatible, opening the default Themes, Creative or Email section
(applications, appearance, app-settings). prefs.email,
prefs.email.set and prefs.email.password are described under App
Settings → Email above.
prefs.execute {id} runs any command a button
or menu would (apps.check, apps.install, appearance.apply,
appearance.revert, …), and prefs.commands lists them with their
enablement. The window is drivable like every MixOS app
(prefs.ui.*, prefs.window). The verbs are registered in
docs/docs/spec/bus/verbs.conf.mix.
For scripted work, call the services directly (releases.*,
settings.*): Prefs is their window, not a second implementation.
Wallpaper
In Appearance → Wallpapers, choose the default or an output, then Theme,
Colour or Image. Colour accepts a picker or #RRGGBB. Browse opens the native
image browser at the installed wallpaper folder, or Pictures in your home
folder. It lists PNG/JPEG files and folders without blocking the window.
Changes stay in Prefs until Apply wallpaper. Revert wallpaper drops
them; Refresh wallpaper reads the current state again.
An output's Use default removes just that override. Editing the default preserves every output override. Images currently crop to fill; fit controls and slideshows will follow when backdrop supports them.
Backdrop must be running on the same session Bus. A refusal shows its reason, keeps the draft and leaves the last good wallpaper in place. Prefs checks for intervening changes before sending the whole document; conflicts require Revert and a fresh edit. This check is best effort: backdrop does not yet provide an atomic compare-and-set operation. A lost reply is checked by a state read, never automatically resent.
Wallpaper and browser state are included in prefs.info, wallpaper state in
prefs.appearance. Commands wallpaper.apply, wallpaper.revert,
wallpaper.refresh and wallpaper.browse are available through
prefs.execute; the normal prefs.ui.* verbs drive the controls and browser.
Running and testing
Run with prefs [--noded-url URL]; a second launch raises the first window
(prefs.show). The Bus connection is citizen.
The source is apps/prefs:
| Path | What |
|---|---|
crates/preferences | the headless engine: panels, rows, notes, one operation at a time, the prefs.* verbs |
crates/preferences/src/appearance.rs | the Appearance panel: the look, its draft, fenced applies, receipts for lost replies |
crates/preferences/src/email.rs | App Settings → Email: account changes planned and checked, fenced applies, passwords handed to Email |
src/commands.rs | every action as a registered command (menus, buttons, shortcuts, prefs.execute) |
src/view.rs | the egui rendering; returns what the person did |
src/shell.rs | events in, effects out, in order; drained shutdown |
i18n/en/prefs.ftl | the strings |
Test with cargo test -p preferences -p prefs. Regenerate the snapshots
with UPDATE_SNAPSHOTS=1 and look at the images before committing them.