GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Support XDG Base Directory specification for config paths
src/color.rs | 18 +++++++-----------
src/config.rs | 33 ++++++++++++++++++++++++++-------
src/layout.rs | 10 +++-------
src/widget/display/graph.rs | 21 ++++++++-------------
src/widget/input/keybinds_control.rs | 12 ++++++++----
src/widget/input/multi_control.rs | 9 +++++++--
6 files changed, 59 insertions(+), 44 deletions(-)
diff --git a/src/color.rs b/src/color.rs
index 9ca5b43..4539bc0 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -79,13 +79,9 @@ pub fn node_drag_color() -> [f32; 4] {
}
fn read_config() -> Option<String> {
- let paths = [
- "/home/lsgalante/.config/cce/config.json",
- ];
- for path in &paths {
- if let Ok(content) = std::fs::read_to_string(path) {
- return Some(content);
- }
+ let path = crate::config::get_config_path();
+ if let Ok(content) = std::fs::read_to_string(&path) {
+ return Some(content);
}
None
}
@@ -530,8 +526,8 @@ pub fn active_window_mode() -> String {
return "floating".to_string();
}
- let config_path = "/home/lsgalante/.config/cce/config.json";
- let content = match std::fs::read_to_string(config_path) {
+ let config_path = crate::config::get_config_path();
+ let content = match std::fs::read_to_string(&config_path) {
Ok(c) => c,
Err(_) => return "floating".to_string(),
};
@@ -573,8 +569,8 @@ pub fn active_window_mode() -> String {
pub fn active_backplate_opacity() -> f32 {
let mode = active_window_mode();
- let config_path = "/home/lsgalante/.config/cce/config.json";
- let content = match std::fs::read_to_string(config_path) {
+ let config_path = crate::config::get_config_path();
+ let content = match std::fs::read_to_string(&config_path) {
Ok(c) => c,
Err(_) => return 0.9,
};
diff --git a/src/config.rs b/src/config.rs
index 2855618..c0ad2ff 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -34,30 +34,49 @@ pub fn update_json_in_memory(val_obj: &mut Value, key: &str, value: &str, defaul
updated
}
+pub fn get_config_path() -> std::path::PathBuf {
+ let dir = if let Ok(xdg_config) = std::env::var("XDG_CONFIG_HOME") {
+ if !xdg_config.is_empty() {
+ std::path::PathBuf::from(xdg_config)
+ } else {
+ let home = std::env::var("HOME").unwrap_or_else(|_| "/home/lsgalante".to_string());
+ std::path::PathBuf::from(home).join(".config")
+ }
+ } else {
+ let home = std::env::var("HOME").unwrap_or_else(|_| "/home/lsgalante".to_string());
+ std::path::PathBuf::from(home).join(".config")
+ };
+ dir.join("cce").join("config.json")
+}
+
fn perform_rolling_backup(path: &str) {
- if path != "/home/lsgalante/.config/cce/config.json" {
+ let config_path = get_config_path();
+ if std::path::Path::new(path) != config_path {
return;
}
if !std::path::Path::new(path).exists() {
return;
}
- let backup_dir = "/home/lsgalante/.config/cce/backups";
- if let Err(_) = fs::create_dir_all(backup_dir) {
+ let backup_dir = config_path.parent().unwrap().join("backups");
+ if let Err(_) = fs::create_dir_all(&backup_dir) {
return;
}
for i in (1..=4).rev() {
- let src = format!("{}/config.json.{}.bak", backup_dir, i);
- let dst = format!("{}/config.json.{}.bak", backup_dir, i + 1);
- if std::path::Path::new(&src).exists() {
+ let src = backup_dir.join(format!("config.json.{}.bak", i));
+ let dst = backup_dir.join(format!("config.json.{}.bak", i + 1));
+ if src.exists() {
let _ = fs::rename(src, dst);
}
}
- let dst = format!("{}/config.json.1.bak", backup_dir);
+ let dst = backup_dir.join("config.json.1.bak");
let _ = fs::copy(path, dst);
}
fn safe_write(path: &str, content: &str) -> bool {
perform_rolling_backup(path);
+ if let Some(parent) = std::path::Path::new(path).parent() {
+ let _ = fs::create_dir_all(parent);
+ }
let temp_path = format!("{}.tmp", path);
if fs::write(&temp_path, content).is_ok() {
if fs::rename(&temp_path, path).is_ok() {
diff --git a/src/layout.rs b/src/layout.rs
index f6c6fcb..c989b30 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -3,12 +3,9 @@ use crate::context::UiContext;
use std::sync::RwLock;
fn read_config() -> Option<String> {
- let paths = [
- "/home/lsgalante/.config/cce/config.json",
- ];
- for path in &paths {
- if let Ok(content) = std::fs::read_to_string(path) {
- if let Ok(val) = serde_json::from_str::<serde_json::Value>(&content) {
+ let path = crate::config::get_config_path();
+ if let Ok(content) = std::fs::read_to_string(&path) {
+ if let Ok(val) = serde_json::from_str::<serde_json::Value>(&content) {
let mut toml_like = String::new();
if let Some(layout) = val.get("layout").and_then(|l| l.as_object()) {
for (k, v) in layout {
@@ -52,7 +49,6 @@ fn read_config() -> Option<String> {
}
}
return Some(toml_like);
- }
}
}
None
diff --git a/src/widget/display/graph.rs b/src/widget/display/graph.rs
index cd1b220..8fd492b 100644
--- a/src/widget/display/graph.rs
+++ b/src/widget/display/graph.rs
@@ -197,20 +197,15 @@ impl Graph {
fn read_zoom_bindings() -> (String, String) {
let mut zoom_in_val = "=".to_string();
let mut zoom_out_val = "-".to_string();
- let paths = [
- "/home/lsgalante/.config/cce/config.json",
- ];
- for path in &paths {
- if let Ok(content) = std::fs::read_to_string(path) {
- if let Ok(val) = serde_json::from_str::<serde_json::Value>(&content) {
- if let Some(zoom_in) = val.pointer("/layout/zoom_in").and_then(|v| v.as_str()) {
- zoom_in_val = zoom_in.to_string();
- }
- if let Some(zoom_out) = val.pointer("/layout/zoom_out").and_then(|v| v.as_str()) {
- zoom_out_val = zoom_out.to_string();
- }
+ let path = crate::config::get_config_path();
+ if let Ok(content) = std::fs::read_to_string(&path) {
+ if let Ok(val) = serde_json::from_str::<serde_json::Value>(&content) {
+ if let Some(zoom_in) = val.pointer("/layout/zoom_in").and_then(|v| v.as_str()) {
+ zoom_in_val = zoom_in.to_string();
+ }
+ if let Some(zoom_out) = val.pointer("/layout/zoom_out").and_then(|v| v.as_str()) {
+ zoom_out_val = zoom_out.to_string();
}
- break;
}
}
(zoom_in_val, zoom_out_val)
diff --git a/src/widget/input/keybinds_control.rs b/src/widget/input/keybinds_control.rs
index 1a14a19..219509e 100644
--- a/src/widget/input/keybinds_control.rs
+++ b/src/widget/input/keybinds_control.rs
@@ -53,7 +53,8 @@ impl KeybindsControl {
}
pub fn load_from_config(&mut self) {
- let content = std::fs::read_to_string("/home/lsgalante/.config/cce/config.json").unwrap_or_default();
+ let path = crate::config::get_config_path();
+ let content = std::fs::read_to_string(&path).unwrap_or_default();
let val: serde_json::Value = serde_json::from_str(&content).unwrap_or_default();
let mut loaded = Vec::new();
if let Some(arr) = val.get("keybind").and_then(|k| k.as_array()) {
@@ -82,8 +83,11 @@ impl KeybindsControl {
}
pub fn save_to_config(&self) {
- let path = "/home/lsgalante/.config/cce/config.json";
- let content = std::fs::read_to_string(path).unwrap_or_default();
+ let path = crate::config::get_config_path();
+ if let Some(parent) = path.parent() {
+ let _ = std::fs::create_dir_all(parent);
+ }
+ let content = std::fs::read_to_string(&path).unwrap_or_default();
let mut val: serde_json::Value = serde_json::from_str(&content).unwrap_or_default();
let mut keybinds = Vec::new();
@@ -123,7 +127,7 @@ impl KeybindsControl {
}
if let Ok(updated_str) = serde_json::to_string_pretty(&val) {
- let _ = std::fs::write(path, updated_str);
+ let _ = std::fs::write(&path, updated_str);
}
}
}
diff --git a/src/widget/input/multi_control.rs b/src/widget/input/multi_control.rs
index 2b88da8..248002e 100644
--- a/src/widget/input/multi_control.rs
+++ b/src/widget/input/multi_control.rs
@@ -961,8 +961,13 @@ impl Element for MultiControl {
impl Control for MultiControl {}
fn get_application_config_path() -> std::path::PathBuf {
- let home = std::env::var("HOME").unwrap_or_else(|_| "/home/lsgalante".to_string());
- let base_dir = std::path::PathBuf::from(home).join(".config").join("cce");
+ let base_dir = crate::config::get_config_path()
+ .parent()
+ .map(|p| p.to_path_buf())
+ .unwrap_or_else(|| {
+ let home = std::env::var("HOME").unwrap_or_else(|_| "/home/lsgalante".to_string());
+ std::path::PathBuf::from(home).join(".config").join("cce")
+ });
let mut app_name = std::env::current_exe()
.ok()