Resolve every base directory in one place, and on Windows
Five sites each read XDG_*_HOME and fell back to $HOME/.local/… on their own, which is fine on Linux and wrong everywhere else: Windows sets neither variable, so every one of them degraded to a path relative to the working directory — for a Start Menu launch, C:\Windows\System32. The models lookup walked XDG_DATA_DIRS the same way. dr_plat::dirs now holds the rule per platform: XDG on Unix, the known folders on Windows — %APPDATA% for config, which roams, and %LOCALAPPDATA% for data and state, which do not — and the executable's own directory as the system data dir, which is where the installer puts the models. The Android overrides stay where they were; only the fallback behind them moved. Both rule sets are unit-tested on either host, and the Windows one was confirmed by running the application under Wine: its log landed in AppData\Local\darkroom\state and nothing was written anywhere else.
This commit is contained in:
+18
-29
@@ -1155,18 +1155,16 @@ pub fn place_path(account: &Account) -> PathBuf {
|
||||
/// reached the server, is the worst failure this application can have, and
|
||||
/// it would be silent.
|
||||
///
|
||||
/// `AccountStore::data_dir()` is the persistent per-app directory the
|
||||
/// Android entry point establishes before anything opens a store. On a
|
||||
/// desktop it is the XDG config directory, and the two lines below keep the
|
||||
/// established XDG *data* location there rather than moving anyone's
|
||||
/// catalog.
|
||||
/// `dr_sync::account::declared_data_dir` is the persistent per-app directory
|
||||
/// the Android entry point establishes before anything opens a store. A
|
||||
/// desktop declares nothing and takes the platform's data directory from
|
||||
/// `dr_plat::dirs` — XDG on Linux, `%LOCALAPPDATA%` on Windows — which keeps
|
||||
/// the established location on Linux rather than moving anyone's catalog.
|
||||
fn data_root() -> PathBuf {
|
||||
let base = std::env::var_os("XDG_DATA_HOME")
|
||||
.map(PathBuf::from)
|
||||
.or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".local/share")))
|
||||
.unwrap_or_else(dr_sync::AccountStore::data_dir);
|
||||
|
||||
base.join("darkroom")
|
||||
match dr_sync::account::declared_data_dir() {
|
||||
Some(declared) => declared.join("darkroom"),
|
||||
None => dr_plat::base_dir(dr_plat::Base::Data),
|
||||
}
|
||||
}
|
||||
|
||||
/// TRACES: FR-NC-10 | NFR-R1
|
||||
@@ -4696,25 +4694,16 @@ pub fn scene_model(account: &Account) -> Option<(PathBuf, PathBuf, PathBuf)> {
|
||||
|
||||
/// Where a *package* may have installed the models.
|
||||
///
|
||||
/// `$XDG_DATA_DIRS` rather than a hard-coded `/usr/share`, because that is the
|
||||
/// variable a distribution, a prefix install, or a Nix-style store sets to say
|
||||
/// where its data went, and the default it falls back to is exactly the pair of
|
||||
/// paths that would otherwise have been hard-coded.
|
||||
///
|
||||
/// Empty on Android, which has no such directories: there the APK's copy is
|
||||
/// unpacked into the shared user directory instead, because an asset inside a
|
||||
/// package is not a path anything can read from (ARCH §6.9).
|
||||
/// `dr_plat::system_data_dirs` has the rule per platform: `$XDG_DATA_DIRS` on
|
||||
/// Linux, the executable's own directory on Windows, nothing on Android —
|
||||
/// there the APK's copy is unpacked into the shared user directory instead,
|
||||
/// because an asset inside a package is not a path anything can read from
|
||||
/// (ARCH §6.9). Last in the search order on every platform, so a pair the
|
||||
/// user placed by hand outranks the installed one.
|
||||
fn system_face_models_dirs() -> Vec<PathBuf> {
|
||||
if cfg!(target_os = "android") {
|
||||
return Vec::new();
|
||||
}
|
||||
let dirs = std::env::var("XDG_DATA_DIRS")
|
||||
.ok()
|
||||
.filter(|v| !v.is_empty())
|
||||
.unwrap_or_else(|| "/usr/local/share:/usr/share".into());
|
||||
dirs.split(':')
|
||||
.filter(|d| !d.is_empty())
|
||||
.map(|d| PathBuf::from(d).join("darkroom").join("models"))
|
||||
dr_plat::system_data_dirs()
|
||||
.into_iter()
|
||||
.map(|d| d.join("models"))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user