Settings and files
How a FlickOS setting is owned, stored, changed and applied. These rules are why a change made in Settings, in the panel, with a key or on the command line always ends up the same, and why nothing FlickOS does can damage a user’s own configuration.
Owning a setting
Section titled “Owning a setting”SET-1 Must: Every setting has exactly one owner
Section titled “SET-1 Must: Every setting has exactly one owner”One program stores a setting and applies it. Everything else, Settings included, asks that program. No two programs write the same file.
| Setting | Owner |
|---|---|
| Layout, style, desktop clicks, clock, apps button, menu style | flickos-layout |
| Tiling | flick-tiler |
| Mouse, touchpad, keyboard, idle, language, night light, Do Not Disturb, startup apps | flickos-control |
| Time, time zone | timedatectl (systemd) |
Animations (enable-animations) |
GSettings; flickos-control animations changes it and records it |
| System language | localectl (systemd) |
A page in Settings for a setting it doesn’t own is a view: it reads with the
owner’s list/current/status/state and changes things by running the
owner’s set. It never opens the owner’s files.
SET-2 Must: CLI first: every setting is a command
Section titled “SET-2 Must: CLI first: every setting is a command”A setting exists on the command line before it gets a page. The owner has commands a user could type:
flickos-layout clicks list # the choices: id, name, descriptionflickos-layout clicks current # the one in useflickos-layout clicks set both-menuflickos-control get [KEY] # key, value, where it comes fromflickos-control set KEY VALUE|defaultlistprints one choice per line, fields separated by tabs, id first.setapplies the change at once and exits 0, or prints why not and exits 1.- When a page needs many values at once, the owner gets a command that prints
them all as JSON (
flickos-layout state). One run replaces many, and Python starting up is most of what a run costs. - When a page needs something the owner can’t do, add it to the owner
(
flick-tiler floating add), not to the page.
This keeps every setting scriptable, testable in the boot test without a window, and usable over ssh when the desktop is broken.
SET-3 Should: Add a setting only when a default won’t do
Section titled “SET-3 Should: Add a setting only when a default won’t do”Every setting is a row to read, a code path to test and a way for two computers to behave differently. Before adding one, try to find a default that suits almost everyone. Add the setting when people really do want different things (12-hour or 24-hour clock), or when the default can’t be known (keyboard layout).
Storing it
Section titled “Storing it”SET-4 Must: System defaults in /etc/xdg/flickos/, user choices in ~/.config/flickos/
Section titled “SET-4 Must: System defaults in /etc/xdg/flickos/, user choices in ~/.config/flickos/”- System default: a conffile,
/etc/xdg/flickos/NAME.conf, in the owner’s package. An administrator or a custom build changes the default for every account there, and dpkg keeps their change on upgrade. - User choice:
~/.config/flickos/NAME, written only when the user changes something. Absent means “use the system default”. - Format: INI (
configparser) orKEY=valuelines, with a comment at the top saying which program writes it and where to change it. - Broken or missing: a file that can’t be read is treated as absent, with a warning on stderr. Never refuse to start because of a config file.
- Not a choice: a record of what happened goes in
$XDG_STATE_HOME/flickos/(~/.local/state/flickos/), not in~/.config. The history of changes (history.jsonl) is the only one so far. Every owner appends its changes there with its ownrecord()in the same format (design).
SET-5 Must: Never write into files the user owns
Section titled “SET-5 Must: Never write into files the user owns”FlickOS never creates, edits or deletes the user’s configuration for other
programs: ~/.config/labwc/, ~/.config/waybar/, ~/.config/foot/, GTK’s
settings.ini, and the like. It also never copies FlickOS config into $HOME,
because a copied file stops getting updates.
What FlickOS needs is generated into the overlay, $XDG_RUNTIME_DIR/flickos/:
- regenerated at every login (
flickos-layout prepare,flickos-control prepare), - written atomically (SET-6),
- deleted when not needed (the default layout and style have no rc.xml overlay),
- in RAM, so it never outlives the session.
When a user’s own file blocks a FlickOS setting (their rc.xml hides the
overlay), say so: flickos-layout doctor lists it, and Settings shows the
warning on the page it affects.
Exceptions: FlickOS’s own files under ~/.config/flickos/, and the files a
setting is about, changed with that setting’s standard tool:
~/.config/mimeapps.list through xdg-mime, ~/.config/autostart/ for
startup applications, ~/.config/xdg-terminals.list for the default
terminal.
SET-6 Must: Write files atomically
Section titled “SET-6 Must: Write files atomically”Write to a temporary file in the same folder, then rename it over the old one
(write_atomic() in flickos-control). A crash, a full disk or a second
process reading at the same moment must never see half a file.
Changing it
Section titled “Changing it”SET-7 Must: A change applies at once
Section titled “SET-7 Must: A change applies at once”Changing a setting takes effect immediately, without logging out: labwc
reloads (flickos-layout reconfigure), the panel restarts, the daemon gets a
signal. When a setting really can’t apply until later, the row says when:
“From the next login”, “The login screen uses it at its next start”.
SET-8 Must: Every setting can go back to its default
Section titled “SET-8 Must: Every setting can go back to its default”set KEY default (or the owner’s equivalent) stores the default, and every
choice list includes the default. labwc never resets an option that
disappears from its config, so “default” writes the default value
explicitly rather than removing the line.
SET-9 Must: Change a shared setting only while it still holds FlickOS’s value
Section titled “SET-9 Must: Change a shared setting only while it still holds FlickOS’s value”Some settings belong to everyone: the GTK theme, the icon theme, GTK’s window
button layout. FlickOS changes one only while it holds a value FlickOS set.
flickos-layout style set changes gtk-theme only while it is one of the
styles’ themes, so a theme chosen in nwg-look is kept. A layout changes
button-layout only while it holds the default or a layout’s value.
System settings
Section titled “System settings”SET-10 Must: System changes go through pkexec and a checked helper
Section titled “SET-10 Must: System changes go through pkexec and a checked helper”A change outside the user’s account (another user, /etc, a system service)
runs through polkit, never through sudo or a root GUI.
- Prefer a system service that already asks polkit itself:
timedatectl,localectl, logind. - Otherwise add a verb to the package’s helper,
/usr/libexec/flickos/NAME-helper(today onlycontrol-helper), run withpkexec:- one polkit action per verb (
org.flickos.control.VERB, matched withorg.freedesktop.policykit.exec.argv1), with a<message>that says what will change in plain words, auth_admin_keepfor the active session,auth_adminotherwise,- every argument checked against a fixed list or pattern before anything changes, and the helper exits with an error on anything else,
- acting on the calling user only (
PKEXEC_UID) unless the verb is about other users, and then never on the calling user’s own account, a logged-in account or the last administrator.
- one polkit action per verb (
- The GUI stays a normal user process. It shows “Waiting for the password…” while pkexec asks.
- A verb that only reads, and whose answer the GUI must share with a verb
that changes (the software undo’s plan:
packages-list,packages-plan), may run without pkexec and has no polkit action. The helper lists them inREAD_ONLYand refuses every other verb without root. Keep the checks in the helper, not in the GUI, so what runs as root is what was shown.