Remove the `directories` dependency (#4904)
eframe now has its own logic to find the storage_dir to persist the app when the persistence feature is enabled, instead of using the directories crate. The directory should be the same as before (verified with a unit test). * Closes <https://github.com/emilk/egui/issues/4884> * [x] I have followed the instructions in the PR template
This commit is contained in:
parent
2a6a1302b8
commit
edea5a40b9
|
|
@ -1180,6 +1180,7 @@ dependencies = [
|
|||
"glow",
|
||||
"glutin",
|
||||
"glutin-winit",
|
||||
"home",
|
||||
"image",
|
||||
"js-sys",
|
||||
"log",
|
||||
|
|
@ -1200,6 +1201,7 @@ dependencies = [
|
|||
"web-time",
|
||||
"wgpu",
|
||||
"winapi",
|
||||
"windows-sys 0.52.0",
|
||||
"winit",
|
||||
]
|
||||
|
||||
|
|
@ -2059,11 +2061,11 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
|||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.5"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ document-features = " 0.2.8"
|
|||
glow = "0.13"
|
||||
glutin = "0.32.0"
|
||||
glutin-winit = "0.5.0"
|
||||
home = "0.5.9"
|
||||
image = { version = "0.25", default-features = false }
|
||||
log = { version = "0.4", features = ["std"] }
|
||||
nohash-hasher = "0.2"
|
||||
|
|
@ -95,6 +96,7 @@ wgpu = { version = "22.1.0", default-features = false, features = [
|
|||
# Make the renderer `Sync` even on wasm32, because it makes the code simpler:
|
||||
"fragile-send-sync-non-atomic-wasm",
|
||||
] }
|
||||
windows-sys = "0.52"
|
||||
winit = { version = "0.30.5", default-features = false }
|
||||
|
||||
[workspace.lints.rust]
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ glow = ["dep:egui_glow", "dep:glow", "dep:glutin-winit", "dep:glutin"]
|
|||
|
||||
## Enable saving app state to disk.
|
||||
persistence = [
|
||||
"directories",
|
||||
"dep:home",
|
||||
"egui-winit/serde",
|
||||
"egui/persistence",
|
||||
"ron",
|
||||
|
|
@ -148,7 +148,6 @@ image = { workspace = true, features = ["png"] } # Needed for app icon
|
|||
winit = { workspace = true, default-features = false, features = ["rwh_06"] }
|
||||
|
||||
# optional native:
|
||||
directories = { version = "5", optional = true }
|
||||
egui-wgpu = { workspace = true, optional = true, features = [
|
||||
"winit",
|
||||
] } # if wgpu is used, use it with winit
|
||||
|
|
@ -158,6 +157,7 @@ pollster = { version = "0.3", optional = true } # needed for wgpu
|
|||
# this can be done at the same time we expose x11/wayland features of winit crate.
|
||||
glutin = { workspace = true, optional = true }
|
||||
glutin-winit = { workspace = true, optional = true }
|
||||
home = { workspace = true, optional = true }
|
||||
puffin = { workspace = true, optional = true }
|
||||
wgpu = { workspace = true, optional = true, features = [
|
||||
# Let's enable some backends so that users can use `eframe` out-of-the-box
|
||||
|
|
@ -185,6 +185,7 @@ objc2-app-kit = { version = "0.2.0", features = [
|
|||
# windows:
|
||||
[target.'cfg(any(target_os = "windows"))'.dependencies]
|
||||
winapi = { version = "0.3.9", features = ["winuser"] }
|
||||
windows-sys = { workspace = true, features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_System_Com"] }
|
||||
|
||||
# -------------------------------------------
|
||||
# web:
|
||||
|
|
@ -253,3 +254,7 @@ wgpu = { workspace = true, optional = true, features = [
|
|||
# without having to explicitly opt-in to backends
|
||||
"webgpu",
|
||||
] }
|
||||
|
||||
# Native dev dependencies for testing
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||
directories = "5"
|
||||
|
|
|
|||
|
|
@ -351,8 +351,8 @@ pub struct NativeOptions {
|
|||
/// persisted (only if the "persistence" feature is enabled).
|
||||
pub persist_window: bool,
|
||||
|
||||
/// The folder where `eframe` will store the app state. If not set, eframe will get the paths
|
||||
/// from [directories].
|
||||
/// The folder where `eframe` will store the app state. If not set, eframe will use a default
|
||||
/// data storage path for each target system.
|
||||
pub persistence_path: Option<std::path::PathBuf>,
|
||||
|
||||
/// Controls whether to apply dithering to minimize banding artifacts.
|
||||
|
|
|
|||
|
|
@ -10,13 +10,80 @@ use std::{
|
|||
/// [`egui::ViewportBuilder::app_id`] of [`crate::NativeOptions::viewport`]
|
||||
/// or the title argument to [`crate::run_native`].
|
||||
///
|
||||
/// On native the path is picked using [`directories::ProjectDirs::data_dir`](https://docs.rs/directories/5.0.1/directories/struct.ProjectDirs.html#method.data_dir) which is:
|
||||
/// On native, the path is:
|
||||
/// * Linux: `/home/UserName/.local/share/APP_ID`
|
||||
/// * macOS: `/Users/UserName/Library/Application Support/APP_ID`
|
||||
/// * Windows: `C:\Users\UserName\AppData\Roaming\APP_ID`
|
||||
/// * Windows: `C:\Users\UserName\AppData\Roaming\APP_ID\data`
|
||||
pub fn storage_dir(app_id: &str) -> Option<PathBuf> {
|
||||
directories::ProjectDirs::from("", "", app_id)
|
||||
.map(|proj_dirs| proj_dirs.data_dir().to_path_buf())
|
||||
use egui::os::OperatingSystem as OS;
|
||||
use std::env::var_os;
|
||||
match OS::from_target_os() {
|
||||
OS::Nix => var_os("XDG_DATA_HOME")
|
||||
.map(PathBuf::from)
|
||||
.filter(|p| p.is_absolute())
|
||||
.or_else(|| home::home_dir().map(|p| p.join(".local").join("share")))
|
||||
.map(|p| {
|
||||
p.join(
|
||||
app_id
|
||||
.to_lowercase()
|
||||
.replace(|c: char| c.is_ascii_whitespace(), ""),
|
||||
)
|
||||
}),
|
||||
OS::Mac => home::home_dir().map(|p| {
|
||||
p.join("Library")
|
||||
.join("Application Support")
|
||||
.join(app_id.replace(|c: char| c.is_ascii_whitespace(), "-"))
|
||||
}),
|
||||
OS::Windows => roaming_appdata().map(|p| p.join(app_id).join("data")),
|
||||
OS::Unknown | OS::Android | OS::IOS => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from
|
||||
// https://github.com/rust-lang/cargo/blob/6e11c77384989726bb4f412a0e23b59c27222c34/crates/home/src/windows.rs#L19-L37
|
||||
#[cfg(all(windows, not(target_vendor = "uwp")))]
|
||||
#[allow(unsafe_code)]
|
||||
fn roaming_appdata() -> Option<PathBuf> {
|
||||
use std::ffi::OsString;
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
use windows_sys::Win32::Foundation::S_OK;
|
||||
use windows_sys::Win32::System::Com::CoTaskMemFree;
|
||||
use windows_sys::Win32::UI::Shell::{
|
||||
FOLDERID_RoamingAppData, SHGetKnownFolderPath, KF_FLAG_DONT_VERIFY,
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn wcslen(buf: *const u16) -> usize;
|
||||
}
|
||||
unsafe {
|
||||
let mut path = ptr::null_mut();
|
||||
match SHGetKnownFolderPath(
|
||||
&FOLDERID_RoamingAppData,
|
||||
KF_FLAG_DONT_VERIFY as u32,
|
||||
0,
|
||||
&mut path,
|
||||
) {
|
||||
S_OK => {
|
||||
let path_slice = slice::from_raw_parts(path, wcslen(path));
|
||||
let s = OsString::from_wide(&path_slice);
|
||||
CoTaskMemFree(path.cast());
|
||||
Some(PathBuf::from(s))
|
||||
}
|
||||
_ => {
|
||||
// Free any allocated memory even on failure. A null ptr is a no-op for `CoTaskMemFree`.
|
||||
CoTaskMemFree(path.cast());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(not(windows), target_vendor = "uwp"))]
|
||||
fn roaming_appdata() -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -171,3 +238,23 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn directories_storage_dir(app_id: &str) -> Option<PathBuf> {
|
||||
directories::ProjectDirs::from("", "", app_id)
|
||||
.map(|proj_dirs| proj_dirs.data_dir().to_path_buf())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn storage_path_matches_directories() {
|
||||
use super::storage_dir;
|
||||
for app_id in [
|
||||
"MyApp", "My App", "my_app", "my-app", "My.App", "my/app", "my:app", r"my\app",
|
||||
] {
|
||||
assert_eq!(directories_storage_dir(app_id), storage_dir(app_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue