settings
An app's own settings file in ~/.config, in KConfig INI format, written atomically under a lock shared with Atlas.Ui's AtlasSettings.
The settings module reads and writes the app's own settings file: $XDG_CONFIG_HOME/atlas-<app>rc, or ~/.config/atlas-<app>rc. The format is KConfig's INI, so KDE tools and the app's C++ and QML side read the same file. AtlasSettings in QML uses the same file and the same lock.
Use it only for Atlas-owned files (atlas-<app>rc). It parses and rewrites the whole file, so do not point it at another program's configuration.
Example
use atlas_framework_core::settings::Settings;
let app = atlas_framework_core::app_info! {
name: "Atlas Notepad",
id: "net.eterneon.atlas.notepad",
repo: "atlasos-notepad",
};
let s = Settings::for_app(&app);
s.set("Restart", "ScheduledAt", Some("1700000000"))?;
assert_eq!(s.get("Restart", "ScheduledAt").as_deref(), Some("1700000000"));
s.set("Restart", "ScheduledAt", None)?; // removes the key
// (the ? operator needs a function that returns io::Result)How writes behave
- Each
setreads the file, changes one key and replaces the file atomically (temp file, sync, rename, then a directory sync). Every other line is kept, and so are the file's mode and, when running as root, its owner. - Writers take a thread lock and an
flockon.<name>.lockbeside the file. The lock file stays on purpose: removing it would race the next writer. Concurrentsetcalls in Atlas code never lose a change. Another program writing the file without the lock can still race, but cannot corrupt it. setwrites nothing, and takes no lock, when the file would not change. This works where the app can read but not write.- A file that cannot be read is never overwritten.
- A symlinked file (dotfiles) keeps its link: the target is written.
- Keys and groups that KConfig marks immutable (
[$i]) are refused. - Values are escaped as KConfig does: a value stays on one line (
\n,\t,\r,\\,\xNNfor other control characters), and leading or trailing spaces are written as\s. - The last of duplicate keys wins when reading, as in KConfig.
Format version
A file carries [Atlas] Format=1 (settings::FORMAT), written when a file is first created or changed. Reading never requires it: files from before it, and files a newer app wrote with a higher number, read the same. Only a change to how existing keys are read would raise it.
Settings
#[derive(Debug, Clone, PartialEq, Eq)]
| Method | Description |
|---|---|
fn for_app(app: &AppInfo) -> Settings |
The file <short_name>rc in config_dir(), for example atlas-updaterrc |
fn at(path: impl Into<PathBuf>) -> Settings |
Any path |
fn path(&self) -> &Path |
The file's path |
fn get(&self, group: &str, key: &str) -> Option<String> |
The unescaped value, or None if the file, group or key is missing |
fn get_bool(&self, group: &str, key: &str) -> Option<bool> |
true, 1, yes, on and false, 0, no, off (any case); anything else, or a missing key, is None |
fn set(&self, group: &str, key: &str, value: Option<&str>) -> io::Result<()> |
Sets the key, or removes it for None. Errors: InvalidInput for a group or key that cannot be written as one (empty, control characters, brackets, = in a key, edge spaces, a leading # or ;), PermissionDenied for an immutable one, NotFound when there is no home directory |
Functions and constants
| Name | Kind | Description |
|---|---|---|
FORMAT |
pub const u32 |
The format version written, 1 |
config_dir() |
pub fn config_dir() -> PathBuf |
$XDG_CONFIG_HOME, else ~/.config. Relative values are ignored, as the XDG spec says. With neither, /nonexistent, where nothing is written |
get_in |
pub fn get_in(text: &str, group: &str, key: &str) -> Option<String> |
Reads a value from KConfig text you already hold |
set_in |
pub fn set_in(text: &str, group: &str, key: &str, value: Option<&str>) -> String |
Returns text with the key set (escaped) or removed. Does no file work and no name checks |