system settings
git clone https://git.lucas.co/cce-system-interface.git
Transition from JSON to KDL format configuration
Cargo.toml | 7 +-
Makefile | 2 +-
scratch/click_add.py | 66 ++++++++
scratch/find_add_button.py | 21 +++
scratch/scroll_and_screenshot.py | 42 +++++
scratch/scroll_keybindings.py | 47 ++++++
src/config_manager.rs | 8 +-
src/input_handler.rs | 4 +-
src/main.rs | 31 ++--
src/pages/display.rs | 11 +-
src/pages/input.rs | 8 +-
src/pages/interface.rs | 330 +++++++++++++++++----------------------
src/pages/storage.rs | 4 +-
src/pages/system_info.rs | 30 ++--
src/renderer.rs | 4 +-
src/watchers.rs | 4 +-
16 files changed, 370 insertions(+), 249 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 5a09a69..f33f50e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "cce-system-settings"
+name = "cce-settings"
version = "0.1.0"
edition = "2021"
@@ -20,12 +20,13 @@ zbus = "5"
futures = "0.3"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
+kdl = "4.6"
reqwest = { version = "0.12", features = ["json"] }
[lib]
-name = "cce_system_settings"
+name = "cce_settings"
path = "src/lib.rs"
[[bin]]
path = "src/main.rs"
-name = "cce-system-settings"
+name = "cce-settings"
diff --git a/Makefile b/Makefile
index a046f21..a9efa49 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ build:
install: build
mkdir -p ~/.local/bin
- install -m 755 ../target/release/cce-system-settings ~/.local/bin/cce-system-settings
+ install -m 755 ../target/release/cce-settings ~/.local/bin/cce-settings
run:
cargo run
diff --git a/scratch/click_add.py b/scratch/click_add.py
new file mode 100644
index 0000000..f1e7b3e
--- /dev/null
+++ b/scratch/click_add.py
@@ -0,0 +1,66 @@
+from PIL import Image
+import subprocess
+import time
+
+# Load the cropped image
+img = Image.open("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/crop_keybindings.png")
+width, height = img.size
+print(f"Crop size: {width}x{height}")
+
+# Find blue button pixels.
+# The button background color is blue, e.g. RGB around [41, 76, 101] or similar.
+# Let's search for pixels where B > R + 15 and B > G + 10, and not too dark or light.
+blue_pixels = []
+for y in range(height):
+ for x in range(width):
+ r, g, b = img.getpixel((x, y))[:3]
+ if b > r + 15 and b > g + 10 and 30 < b < 180:
+ blue_pixels.append((x, y))
+
+if blue_pixels:
+ print(f"Found {len(blue_pixels)} blue pixels.")
+ min_x = min(p[0] for p in blue_pixels)
+ max_x = max(p[0] for p in blue_pixels)
+ min_y = min(p[1] for p in blue_pixels)
+ max_y = max(p[1] for p in blue_pixels)
+
+ print(f"Blue bounding box: X=[{min_x}, {max_x}], Y=[{min_y}, {max_y}]")
+
+ target_pt = ((min_x + max_x) // 2, (min_y + max_y) // 2)
+ print(f"Target center in crop: {target_pt}")
+
+ # Calculate screen coordinates (in physical pixels)
+ # Remember crop starts at: wx = 185 * 2 = 370
+ # wy_crop_start = wy + wh // 2 = 27 * 2 + 1069 = 1123
+ screen_x_physical = 370 + target_pt[0]
+ screen_y_physical = 1123 + target_pt[1]
+
+ # wlrctl pointer move takes coordinates in logical pixels!
+ # Wait, let's divide physical pixels by 2.0 to get logical pixels.
+ logical_x = int(screen_x_physical / 2.0)
+ logical_y = int(screen_y_physical / 2.0)
+ print(f"Clicking at screen logical coords: ({logical_x}, {logical_y})")
+
+ # Reset cursor to top-left
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer move -3000 -3000", shell=True)
+ time.sleep(0.1)
+ # Move to logical coordinates
+ subprocess.run(f"env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer move {logical_x} {logical_y}", shell=True)
+ time.sleep(0.2)
+ # Click
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer click left", shell=True)
+ time.sleep(0.8)
+
+ # Take new screenshot
+ screenshot_path = "/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/screenshot_after_click.png"
+ subprocess.run(f"env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 grim {screenshot_path}", shell=True)
+
+ # Crop again to verify
+ img_new = Image.open(screenshot_path)
+ wx, wy, ww, wh = 185 * 2, 27 * 2, 641 * 2, 1069 * 2
+ crop_box = (wx, wy + wh // 2, wx + ww // 2, wy + wh)
+ cropped_new = img_new.crop(crop_box)
+ cropped_new.save("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/crop_keybindings_after.png")
+ print("Verification crop saved to crop_keybindings_after.png")
+else:
+ print("Could not find blue pixels for Add Keybind button.")
diff --git a/scratch/find_add_button.py b/scratch/find_add_button.py
new file mode 100644
index 0000000..9ad6d20
--- /dev/null
+++ b/scratch/find_add_button.py
@@ -0,0 +1,21 @@
+from PIL import Image
+
+# Load the screenshot
+img = Image.open("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/screenshot_final.png")
+print("Image size:", img.size)
+
+# Scale window bounds by 2
+wx = 100 * 2
+wy = 100 * 2
+ww = 400 * 2
+wh = 680 * 2
+
+# Touchpad is in the upper half of the window
+crop_touchpad = img.crop((wx, wy, wx + ww, wy + wh // 2))
+crop_touchpad.save("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/crop_touchpad_final.png")
+print("Touchpad crop saved.")
+
+# Keybindings is in the lower half of the window
+crop_keybindings = img.crop((wx, wy + wh // 2, wx + ww, wy + wh))
+crop_keybindings.save("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/crop_keybindings_final.png")
+print("Keybindings crop saved.")
diff --git a/scratch/scroll_and_screenshot.py b/scratch/scroll_and_screenshot.py
new file mode 100644
index 0000000..d1039c8
--- /dev/null
+++ b/scratch/scroll_and_screenshot.py
@@ -0,0 +1,42 @@
+import subprocess
+import time
+from PIL import Image
+
+def scroll_content():
+ print("Resetting cursor to top-left...")
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer move -3000 -3000", shell=True)
+ time.sleep(0.1)
+
+ print("Moving cursor to settings window content area...")
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer move 300 440", shell=True)
+ time.sleep(0.2)
+
+ print("Clicking to focus settings window...")
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer click left", shell=True)
+ time.sleep(0.3)
+
+ # Scroll down multiple times
+ print("Scrolling down...")
+ for _ in range(35):
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer scroll -15 0", shell=True)
+ time.sleep(0.05)
+
+ time.sleep(0.8)
+
+scroll_content()
+
+# Take screenshot
+screenshot_path = "/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/screenshot_scrolled.png"
+subprocess.run(f"env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 grim {screenshot_path}", shell=True)
+print("Screenshot saved.")
+
+# Crop the bottom-left area of the window
+img = Image.open(screenshot_path)
+wx = 100 * 2
+wy = 100 * 2
+ww = 400 * 2
+wh = 680 * 2
+crop_box = (wx, wy + wh // 2, wx + ww, wy + wh)
+cropped = img.crop(crop_box)
+cropped.save("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/crop_scrolled_final.png")
+print("Crop saved to crop_scrolled_final.png")
diff --git a/scratch/scroll_keybindings.py b/scratch/scroll_keybindings.py
new file mode 100644
index 0000000..225cd5d
--- /dev/null
+++ b/scratch/scroll_keybindings.py
@@ -0,0 +1,47 @@
+import subprocess
+import time
+from PIL import Image
+
+# Kill exact binary path to avoid matching this python script path
+print("Killing existing settings process...")
+subprocess.run('pkill -f "/home/lsgalante/.local/bin/cce-settings"', shell=True)
+time.sleep(0.5)
+
+print("Starting settings application...")
+subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 /home/lsgalante/.local/bin/cce-settings &", shell=True)
+time.sleep(1.5)
+
+print("Focusing window...")
+subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl toplevel focus title:'CCE System Settings'", shell=True)
+time.sleep(0.3)
+
+print("Resetting cursor...")
+subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer move -3000 -3000", shell=True)
+time.sleep(0.1)
+
+print("Moving cursor to safe spot...")
+subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer move 380 250", shell=True)
+time.sleep(0.2)
+
+print("Scrolling down...")
+for _ in range(45):
+ subprocess.run("env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 wlrctl pointer scroll -15 0", shell=True)
+ time.sleep(0.04)
+
+time.sleep(0.8)
+
+# Take screenshot
+screenshot_path = "/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/screenshot_scrolled_ok.png"
+subprocess.run(f"env WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 grim {screenshot_path}", shell=True)
+print("Screenshot saved.")
+
+# Crop Keybindings
+img = Image.open(screenshot_path)
+wx = 100 * 2
+wy = 100 * 2
+ww = 400 * 2
+wh = 680 * 2
+crop_box = (wx, wy + wh // 2, wx + ww, wy + wh)
+cropped = img.crop(crop_box)
+cropped.save("/home/lsgalante/.gemini/antigravity/brain/e9f42138-61bb-4037-ac7e-0b1d2091db1c/crop_scrolled_final.png")
+print("Crop saved.")
diff --git a/src/config_manager.rs b/src/config_manager.rs
index 5b5fda7..2ce566e 100644
--- a/src/config_manager.rs
+++ b/src/config_manager.rs
@@ -1,7 +1,7 @@
use std::fs;
use serde_json::Value;
-pub const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.json";
+pub const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.kdl";
pub fn read_config_file() -> String {
fs::read_to_string(CONFIG_PATH).unwrap_or_default()
@@ -19,13 +19,13 @@ fn perform_rolling_backup(path: &str) {
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);
+ let src = format!("{}/config.kdl.{}.bak", backup_dir, i);
+ let dst = format!("{}/config.kdl.{}.bak", backup_dir, i + 1);
if std::path::Path::new(&src).exists() {
let _ = fs::rename(src, dst);
}
}
- let dst = format!("{}/config.json.1.bak", backup_dir);
+ let dst = format!("{}/config.kdl.1.bak", backup_dir);
let _ = fs::copy(path, dst);
}
diff --git a/src/input_handler.rs b/src/input_handler.rs
index bd33375..a9b36fc 100644
--- a/src/input_handler.rs
+++ b/src/input_handler.rs
@@ -1,6 +1,6 @@
use crate::SystemInterface;
-use cce_system_settings::app::AppAction;
-use cce_system_settings::pages::{self, Page};
+use cce_settings::app::AppAction;
+use cce_settings::pages::{self, Page};
use cce_ui::widget::Element;
impl SystemInterface {
diff --git a/src/main.rs b/src/main.rs
index 16288fc..fc1333f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,8 @@
use cce_ui::widget::{Finger, hover_animation, Element, PageSelector};
use glyphon::{Attrs, Buffer, FontSystem, Metrics};
-use cce_system_settings::app::{AppAction, AppState};
-use cce_system_settings::pages::{self, Page};
+use cce_settings::app::{AppAction, AppState};
+use cce_settings::pages::{self, Page};
mod input_handler;
mod renderer;
@@ -233,7 +233,7 @@ impl cce_ui::engine::Application for SystemInterface {
let current_page_shared = std::sync::Arc::new(std::sync::atomic::AtomicU8::new(initial_page_idx as u8));
let (watchers, tx_backup, rx_backup, tx_update, rx_update) =
- cce_system_settings::watchers::spawn_all(current_page_shared.clone());
+ cce_settings::watchers::spawn_all(current_page_shared.clone());
let (sans_family, serif_family, monospace_family, _, _, _, _) = pages::interface::read_preferred_fonts();
@@ -289,7 +289,7 @@ impl cce_ui::engine::Application for SystemInterface {
rx_packages: watchers.rx_packages,
tx_update,
rx_update,
- last_write_mtime: std::fs::metadata("/home/lsgalante/.config/cce/config.json")
+ last_write_mtime: std::fs::metadata("/home/lsgalante/.config/cce/config.kdl")
.and_then(|m| m.modified())
.unwrap_or_else(|_| std::time::SystemTime::now()),
@@ -346,7 +346,7 @@ impl cce_ui::engine::Application for SystemInterface {
fn settings(&self) -> cce_ui::engine::WindowSettings {
cce_ui::engine::WindowSettings {
title: "CCE System Settings".to_string(),
- app_id: "cce-system-settings".to_string(),
+ app_id: "cce-settings".to_string(),
width: 820,
height: 680,
fullscreen: false,
@@ -360,7 +360,7 @@ impl cce_ui::engine::Application for SystemInterface {
return;
}
self.handle_action(&msg);
- if let Ok(metadata) = std::fs::metadata("/home/lsgalante/.config/cce/config.json") {
+ if let Ok(metadata) = std::fs::metadata("/home/lsgalante/.config/cce/config.kdl") {
if let Ok(mtime) = metadata.modified() {
self.last_write_mtime = mtime;
}
@@ -384,7 +384,7 @@ impl cce_ui::engine::Application for SystemInterface {
self.handle_action(&action);
}
if has_actions {
- if let Ok(metadata) = std::fs::metadata("/home/lsgalante/.config/cce/config.json") {
+ if let Ok(metadata) = std::fs::metadata("/home/lsgalante/.config/cce/config.kdl") {
if let Ok(mtime) = metadata.modified() {
self.last_write_mtime = mtime;
}
@@ -879,16 +879,15 @@ fn main() {
let mut initial_page = Page::ALL[0];
// Try to load last_page from config
- let config_path = "/home/lsgalante/.config/cce/config.json";
+ let config_path = "/home/lsgalante/.config/cce/config.kdl";
if let Ok(content) = std::fs::read_to_string(config_path) {
- if let Ok(val) = serde_json::from_str::<serde_json::Value>(&content) {
- if let Some(last_page_val) = val.pointer("/layout/last_page").and_then(|v| v.as_str()) {
- let last_page_val = last_page_val.trim_matches('"').trim_matches('\'').trim().to_lowercase();
- for page in Page::ALL {
- if page.label().to_lowercase() == last_page_val {
- initial_page = page;
- break;
- }
+ let val = cce_ui::config::parse_kdl_to_json(&content);
+ if let Some(last_page_val) = val.pointer("/layout/last_page").and_then(|v| v.as_str()) {
+ let last_page_val = last_page_val.trim_matches('"').trim_matches('\'').trim().to_lowercase();
+ for page in Page::ALL {
+ if page.label().to_lowercase() == last_page_val {
+ initial_page = page;
+ break;
}
}
}
diff --git a/src/pages/display.rs b/src/pages/display.rs
index c261127..af63473 100644
--- a/src/pages/display.rs
+++ b/src/pages/display.rs
@@ -3,7 +3,7 @@ use crate::pages::interface::get_config_path;
use cce_ui::layout::{PageLayoutBuilder, LayoutStrategy};
use cce_ui::widget::{Spinbox, Label, Element, Toggle, Dropdown, Slider};
-const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.json";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.kdl";
#[derive(Debug, Clone)]
pub struct DisplayOutput {
@@ -113,7 +113,7 @@ pub enum DisplayMessage {
}
fn parse_json(content: &str) -> serde_json::Value {
- serde_json::from_str(content).unwrap_or_default()
+ cce_ui::config::parse_kdl_to_json(content)
}
fn parse_screensaver_enable(content: &str) -> bool {
@@ -702,10 +702,10 @@ mod tests {
fn test_read_write_display_scale() {
use crate::pages::interface::TEST_CONFIG_PATH;
let dir = std::env::temp_dir();
- let path = dir.join("test_display_scale_config.json");
+ let path = dir.join("test_display_scale_config.kdl");
let path_str = path.to_str().unwrap().to_string();
- let initial_content = "{\"display\": {\"scale_eDP-1\": 1.25}}";
+ let initial_content = "display {\n scale_eDP-1 (f64)1.25\n}\n";
std::fs::write(&path_str, initial_content).unwrap();
TEST_CONFIG_PATH.with(|p| *p.borrow_mut() = Some(path_str.clone()));
@@ -715,7 +715,8 @@ mod tests {
TEST_CONFIG_PATH.with(|p| *p.borrow_mut() = None);
let updated = std::fs::read_to_string(&path_str).unwrap();
- assert!(updated.contains("\"scale_eDP-1\": 1.5"));
+ assert!(updated.contains("scale_eDP-1"));
+ assert!(updated.contains("1.5"));
let _ = std::fs::remove_file(path);
}
diff --git a/src/pages/input.rs b/src/pages/input.rs
index 596c5c8..dd62f68 100644
--- a/src/pages/input.rs
+++ b/src/pages/input.rs
@@ -5,7 +5,7 @@ use crate::app::{AppAction, PageContent};
use cce_ui::layout::{PageLayoutBuilder, LayoutStrategy};
use cce_ui::widget::{Spinbox, Toggle, Trackpad, Dropdown, Finger, Element, TextBox, KeybindsControl};
-const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.json";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.kdl";
fn get_socket_path() -> String {
match std::env::var("WAYLAND_DISPLAY") {
@@ -288,7 +288,7 @@ pub fn read_input_config() -> InputState {
}
fn parse_json(content: &str) -> serde_json::Value {
- serde_json::from_str(content).unwrap_or_default()
+ cce_ui::config::parse_kdl_to_json(content)
}
fn json_find_key<'a>(val: &'a serde_json::Value, key: &str) -> Option<&'a serde_json::Value> {
@@ -774,11 +774,11 @@ mod tests {
#[test]
fn test_parse_scrolling_params() {
- let content = r#"{"input": {"natural_scroll": true}, "inertial": {"scroll_speed": 2.5}}"#;
+ let content = "input {\n natural_scroll (bool)true\n}\ninertial {\n scroll_speed (f64)2.5\n}\n";
assert_eq!(parse_bool_from_default(content, "natural_scroll", false), true);
assert_eq!(parse_f32_key(content, "scroll_speed", 1.0), 2.5);
- let empty_content = "{}";
+ let empty_content = "";
assert_eq!(parse_bool_from_default(empty_content, "natural_scroll", false), false);
assert_eq!(parse_f32_key(empty_content, "scroll_speed", 1.0), 1.0);
}
diff --git a/src/pages/interface.rs b/src/pages/interface.rs
index fd28c0c..b354625 100644
--- a/src/pages/interface.rs
+++ b/src/pages/interface.rs
@@ -7,8 +7,8 @@ use cce_ui::widget::{
Slider
};
-const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.json";
-const LINKS_PATH: &str = "/home/lsgalante/.config/cce/cce-system-settings/links.json";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/cce/config.kdl";
+const LINKS_PATH: &str = "/home/lsgalante/.config/cce/cce-settings/links.json";
thread_local! {
pub(crate) static TEST_CONFIG_PATH: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
@@ -60,13 +60,13 @@ fn perform_rolling_backup(path: &str) {
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);
+ let src = format!("{}/config.kdl.{}.bak", backup_dir, i);
+ let dst = format!("{}/config.kdl.{}.bak", backup_dir, i + 1);
if std::path::Path::new(&src).exists() {
let _ = fs::rename(src, dst);
}
}
- let dst = format!("{}/config.json.1.bak", backup_dir);
+ let dst = format!("{}/config.kdl.1.bak", backup_dir);
let _ = fs::copy(path, dst);
}
@@ -1243,7 +1243,7 @@ fn apply_edge_gap(val: u16) {
fn parse_json(content: &str) -> serde_json::Value {
- serde_json::from_str(content).unwrap_or_default()
+ cce_ui::config::parse_kdl_to_json(content)
}
fn json_find_key<'a>(val: &'a serde_json::Value, key: &str) -> Option<&'a serde_json::Value> {
@@ -1342,7 +1342,10 @@ pub fn get_links_path(path: &str) -> Vec<(String, String)> {
pub fn write_config_value_path(path: &str, key: &str, value: &str) -> bool {
let content = fs::read_to_string(path).unwrap_or_default();
- let mut val = parse_json(&content);
+ let mut doc = match content.parse::<kdl::KdlDocument>() {
+ Ok(d) => d,
+ Err(_) => kdl::KdlDocument::new(),
+ };
let mut keys_to_update = vec![key.to_string()];
let links = get_links();
@@ -1371,16 +1374,15 @@ pub fn write_config_value_path(path: &str, key: &str, value: &str) -> bool {
} else {
k
};
- if cce_ui::config::update_json_in_memory(&mut val, mapped_k, value, "layout") {
+ if cce_ui::config::update_kdl_in_memory(&mut doc, mapped_k, value, "layout") {
updated_any = true;
}
}
if updated_any {
- if let Ok(updated_str) = serde_json::to_string_pretty(&val) {
- if safe_write(path, &updated_str) {
- return true;
- }
+ let updated_str = doc.to_string();
+ if safe_write(path, &updated_str) {
+ return true;
}
}
false
@@ -4271,25 +4273,7 @@ pub fn parse_transparency_opacity(content: &str) -> f32 {
}
pub fn write_transparency_config_value(key: &str, value: &str) {
- let path = get_config_path();
- let content = fs::read_to_string(&path).unwrap_or_default();
- let mut val = parse_json(&content);
- let j_val = if let Ok(parsed_val) = serde_json::from_str::<serde_json::Value>(value) {
- parsed_val
- } else {
- serde_json::json!(value)
- };
- if val.get("transparency").is_none() {
- if let Some(obj) = val.as_object_mut() {
- obj.insert("transparency".to_string(), serde_json::Value::Object(serde_json::Map::new()));
- }
- }
- if let Some(transparency) = val.get_mut("transparency").and_then(|t| t.as_object_mut()) {
- transparency.insert(key.to_string(), j_val);
- }
- if let Ok(updated_str) = serde_json::to_string_pretty(&val) {
- let _ = safe_write(&path, &updated_str);
- }
+ cce_ui::config::write_config_value(&get_config_path(), key, value, "transparency");
}
fn write_surfaces_config_value(key: &str, value: &str) {
@@ -4297,24 +4281,7 @@ fn write_surfaces_config_value(key: &str, value: &str) {
}
fn write_surfaces_config_value_path(path: &str, key: &str, value: &str) {
- let content = fs::read_to_string(path).unwrap_or_default();
- let mut val = parse_json(&content);
- let j_val = if let Ok(parsed_val) = serde_json::from_str::<serde_json::Value>(value) {
- parsed_val
- } else {
- serde_json::json!(value)
- };
- if val.get("surfaces").is_none() {
- if let Some(obj) = val.as_object_mut() {
- obj.insert("surfaces".to_string(), serde_json::Value::Object(serde_json::Map::new()));
- }
- }
- if let Some(surfaces) = val.get_mut("surfaces").and_then(|s| s.as_object_mut()) {
- surfaces.insert(key.to_string(), j_val);
- }
- if let Ok(updated_str) = serde_json::to_string_pretty(&val) {
- let _ = safe_write(path, &updated_str);
- }
+ cce_ui::config::write_config_value(path, key, value, "surfaces");
}
fn parse_surfaces_color(content: &str, key: &str, default: [u8; 3]) -> [u8; 3] {
@@ -4361,24 +4328,7 @@ fn write_notifications_config_value(key: &str, value: &str) {
}
fn write_notifications_config_value_path(path: &str, key: &str, value: &str) {
- let content = fs::read_to_string(path).unwrap_or_default();
- let mut val = parse_json(&content);
- let j_val = if let Ok(parsed_val) = serde_json::from_str::<serde_json::Value>(value) {
- parsed_val
- } else {
- serde_json::json!(value)
- };
- if val.get("notifications").is_none() {
- if let Some(obj) = val.as_object_mut() {
- obj.insert("notifications".to_string(), serde_json::Value::Object(serde_json::Map::new()));
- }
- }
- if let Some(notifications) = val.get_mut("notifications").and_then(|n| n.as_object_mut()) {
- notifications.insert(key.to_string(), j_val);
- }
- if let Ok(updated_str) = serde_json::to_string_pretty(&val) {
- let _ = safe_write(path, &updated_str);
- }
+ cce_ui::config::write_config_value(path, key, value, "notifications");
}
@@ -4435,28 +4385,28 @@ mod tests {
#[test]
fn test_parse_color_from_key() {
- let content = r##"{
- "layout": {
- "low_color": "#112233",
- "high_color": "#445566",
- "disabled_color": "#778899",
- "status_separator_color": "#aabbcc",
- "visual_guides_color": "#ddeeff",
- "slider_track_color": "#123456",
- "page_low_color": "#474751",
- "color_borders_color": "#abcdef",
- "status_normal_color": "#ccccd8",
- "paginator_sidebar_color": "#5a5a65",
- "primary_highlight_color": "#ffffff",
- "menubar_tab_label_color": "#e6e6f2",
- "toggle_enabled_color": "#68d8a5",
- "toggle_disabled_color": "#878794",
- "scrollinglist_bg_color": "#515161",
- "breadcrumb_bg_color": "#515161",
- "page_color": "#0a1a0e",
- "layer_color": "#123456"
- }
- }"##;
+ let content = r##"
+ layout {
+ low_color (color)"#112233"
+ high_color (color)"#445566"
+ disabled_color (color)"#778899"
+ status_separator_color (color)"#aabbcc"
+ visual_guides_color (color)"#ddeeff"
+ slider_track_color (color)"#123456"
+ page_low_color (color)"#474751"
+ color_borders_color (color)"#abcdef"
+ status_normal_color (color)"#ccccd8"
+ paginator_sidebar_color (color)"#5a5a65"
+ primary_highlight_color (color)"#ffffff"
+ menubar_tab_label_color (color)"#e6e6f2"
+ toggle_enabled_color (color)"#68d8a5"
+ toggle_disabled_color (color)"#878794"
+ scrollinglist_bg_color (color)"#515161"
+ breadcrumb_bg_color (color)"#515161"
+ page_color (color)"#0a1a0e"
+ layer_color (color)"#123456"
+ }
+ "##;
assert_eq!(parse_color_from_key(content, "low_color", [0, 0, 0]), [17, 34, 51]);
assert_eq!(parse_color_from_key(content, "high_color", [0, 0, 0]), [68, 85, 102]);
assert_eq!(parse_color_from_key(content, "disabled_color", [0, 0, 0]), [119, 136, 153]);
@@ -4480,12 +4430,12 @@ mod tests {
#[test]
fn test_parse_rgba_color_from_key() {
- let content = r##"{
- "layout": {
- "scrollinglist_entry_bg_color": "#ffffff0a",
- "scrollinglist_entry_highlight_color": "#ffffffcc"
- }
- }"##;
+ let content = r##"
+ layout {
+ scrollinglist_entry_bg_color (color)"#ffffff0a"
+ scrollinglist_entry_highlight_color (color)"#ffffffcc"
+ }
+ "##;
assert_eq!(parse_rgba_color_from_key(content, "scrollinglist_entry_bg_color", [0, 0, 0, 0]), [255, 255, 255, 10]);
assert_eq!(parse_rgba_color_from_key(content, "scrollinglist_entry_highlight_color", [0, 0, 0, 0]), [255, 255, 255, 204]);
}
@@ -4497,31 +4447,31 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Write initial file content with [layout] and other keys
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}, \"output\": {\"scale\": 2}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\noutput {\n scale (i64)2\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Write disabled_color which does not exist yet (key not found case)
assert!(write_config_value_path(path_str, "disabled_color", "\"#555555\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"disabled_color\": \"#555555\""));
+ assert!(updated.contains("disabled_color")); assert!(updated.contains("#555555"));
// Check it was inserted before [output]
- assert!(updated.find("\"disabled_color\": \"#555555\"").unwrap() < updated.find("\"output\"").unwrap());
+ assert!(updated.find("disabled_color").unwrap() < updated.find("output").unwrap());
// 3. Update disabled_color (key found case)
assert!(write_config_value_path(path_str, "disabled_color", "\"#666666\""));
let updated2 = fs::read_to_string(path_str).unwrap();
- assert!(updated2.contains("\"disabled_color\": \"#666666\""));
- assert!(!updated2.contains("\"disabled_color\": \"#555555\""));
+ assert!(updated2.contains("disabled_color")); assert!(updated2.contains("#666666"));
+ assert!(!updated2.contains("#555555"));
// 4. Write visual_guides_color which does not exist yet
assert!(write_config_value_path(path_str, "visual_guides_color", "\"#ff8c00\""));
let updated3 = fs::read_to_string(path_str).unwrap();
- assert!(updated3.contains("\"visual_guides_color\": \"#ff8c00\""));
+ assert!(updated3.contains("visual_guides_color")); assert!(updated3.contains("#ff8c00"));
// 5. Write slider_track_color which does not exist yet
assert!(write_config_value_path(path_str, "slider_track_color", "\"#123456\""));
let updated4 = fs::read_to_string(path_str).unwrap();
- assert!(updated4.contains("\"slider_track_color\": \"#123456\""));
+ assert!(updated4.contains("slider_track_color")); assert!(updated4.contains("#123456"));
// Clean up
let _ = fs::remove_file(path_str);
@@ -4560,7 +4510,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse section_padding when missing (should return default 8)
@@ -4571,7 +4521,7 @@ mod tests {
// 3. Write section_padding config
assert!(write_config_value_path(path_str, "section_padding", "12"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"section_padding\": 12"));
+ assert!(updated.contains("section_padding")); assert!(updated.contains("12"));
// 4. Parse section_padding when present (should return written value 12)
let val2 = parse_u16_from(&updated, "section_padding", 8);
@@ -4588,7 +4538,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse plate_padding when missing (should return default 20)
@@ -4599,7 +4549,7 @@ mod tests {
// 3. Write plate_padding config
assert!(write_config_value_path(path_str, "plate_padding", "15"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"plate_padding\": 15"));
+ assert!(updated.contains("plate_padding")); assert!(updated.contains("15"));
// 4. Parse plate_padding when present (should return written value 15)
let val2 = parse_u16_from(&updated, "plate_padding", 20);
@@ -4616,7 +4566,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse page_margin when missing (should return default 20)
@@ -4627,7 +4577,7 @@ mod tests {
// 3. Write page_margin config
assert!(write_config_value_path(path_str, "page_margin", "15"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"page_margin\": 15"));
+ assert!(updated.contains("page_margin")); assert!(updated.contains("15"));
// 4. Parse page_margin when present (should return written value 15)
let val2 = parse_u16_from(&updated, "page_margin", 20);
@@ -4644,7 +4594,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse spinbox_corner_radius when missing (should return default 4)
@@ -4655,7 +4605,7 @@ mod tests {
// 3. Write spinbox_corner_radius config
assert!(write_config_value_path(path_str, "spinbox_corner_radius", "8"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"spinbox_corner_radius\": 8"));
+ assert!(updated.contains("spinbox_corner_radius")); assert!(updated.contains("8"));
// 4. Parse spinbox_corner_radius when present (should return written value 8)
let val2 = parse_u16_from(&updated, "spinbox_corner_radius", 4);
@@ -4672,7 +4622,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse spinbox_height when missing (should return default 26)
@@ -4683,7 +4633,7 @@ mod tests {
// 3. Write spinbox_height config
assert!(write_config_value_path(path_str, "spinbox_height", "30"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"spinbox_height\": 30"));
+ assert!(updated.contains("spinbox_height")); assert!(updated.contains("30"));
// 4. Parse spinbox_height when present (should return written value 30)
let val2 = parse_u16_from(&updated, "spinbox_height", 26);
@@ -4700,7 +4650,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse toggle_height when missing (should return default 44)
@@ -4711,7 +4661,7 @@ mod tests {
// 3. Write toggle_height config
assert!(write_config_value_path(path_str, "toggle_height", "52"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"toggle_height\": 52"));
+ assert!(updated.contains("toggle_height")); assert!(updated.contains("52"));
// 4. Parse toggle_height when present (should return written value 52)
let val2 = parse_u16_from(&updated, "toggle_height", 44);
@@ -4728,7 +4678,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse toggle_corner_radius when missing (should return default 4)
@@ -4739,7 +4689,7 @@ mod tests {
// 3. Write toggle_corner_radius config
assert!(write_config_value_path(path_str, "toggle_corner_radius", "8"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"toggle_corner_radius\": 8"));
+ assert!(updated.contains("toggle_corner_radius")); assert!(updated.contains("8"));
// 4. Parse toggle_corner_radius when present (should return written value 8)
let val2 = parse_u16_from(&updated, "toggle_corner_radius", 4);
@@ -4764,7 +4714,7 @@ mod tests {
assert!(write_config_value_path(path_str, "toggle_bg_color", "\"#123456\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"toggle_bg_color\": \"#123456\""));
+ assert!(updated.contains("toggle_bg_color")); assert!(updated.contains("#123456"));
let val2 = parse_color_from_key(&updated, "toggle_bg_color", [116, 116, 128]);
assert_eq!(val2, [18, 52, 86]);
@@ -4787,7 +4737,7 @@ mod tests {
assert!(write_config_value_path(path_str, "toggle_border_width", "3"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"toggle_border_width\": 3"));
+ assert!(updated.contains("toggle_border_width")); assert!(updated.contains("3"));
let val2 = parse_u16_from(&updated, "toggle_border_width", 1);
assert_eq!(val2, 3);
@@ -4810,7 +4760,7 @@ mod tests {
assert!(write_config_value_path(path_str, "toggle_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"toggle_font\": \"Inter\""));
+ assert!(updated.contains("toggle_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "toggle_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4833,7 +4783,7 @@ mod tests {
assert!(write_config_value_path(path_str, "font_selector_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"font_selector_font\": \"Inter\""));
+ assert!(updated.contains("font_selector_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "font_selector_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4856,7 +4806,7 @@ mod tests {
assert!(write_config_value_path(path_str, "button_strip_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"button_strip_font\": \"Inter\""));
+ assert!(updated.contains("button_strip_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "button_strip_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4879,7 +4829,7 @@ mod tests {
assert!(write_config_value_path(path_str, "button_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"button_font\": \"Inter\""));
+ assert!(updated.contains("button_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "button_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4902,7 +4852,7 @@ mod tests {
assert!(write_config_value_path(path_str, "label_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"label_font\": \"Inter\""));
+ assert!(updated.contains("label_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "label_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4925,7 +4875,7 @@ mod tests {
assert!(write_config_value_path(path_str, "dropdown_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"dropdown_font\": \"Inter\""));
+ assert!(updated.contains("dropdown_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "dropdown_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4948,7 +4898,7 @@ mod tests {
assert!(write_config_value_path(path_str, "textbox_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"textbox_font\": \"Inter\""));
+ assert!(updated.contains("textbox_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "textbox_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -4971,7 +4921,7 @@ mod tests {
assert!(write_config_value_path(path_str, "spinbox_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"spinbox_font\": \"Inter\""));
+ assert!(updated.contains("spinbox_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "spinbox_font", "monospace");
assert_eq!(val2, "Inter");
@@ -4994,7 +4944,7 @@ mod tests {
assert!(write_config_value_path(path_str, "slider_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"slider_font\": \"Inter\""));
+ assert!(updated.contains("slider_font")); assert!(updated.contains("Inter"));
let val2 = parse_string_from(&updated, "slider_font", "Outfit");
assert_eq!(val2, "Inter");
@@ -5009,7 +4959,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse slider_corner_radius when missing (should return default 4)
@@ -5020,7 +4970,7 @@ mod tests {
// 3. Write slider_corner_radius config
assert!(write_config_value_path(path_str, "slider_corner_radius", "6"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"slider_corner_radius\": 6"));
+ assert!(updated.contains("slider_corner_radius")); assert!(updated.contains("6"));
// 4. Parse slider_corner_radius when present (should return written value 6)
let val2 = parse_u16_from(&updated, "slider_corner_radius", 4);
@@ -5037,7 +4987,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse plate_opacity when missing (should return default 1.0)
@@ -5048,7 +4998,7 @@ mod tests {
// 3. Write plate_opacity config
assert!(write_config_value_path(path_str, "plate_opacity", "0.85"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"plate_opacity\": 0.85"));
+ assert!(updated.contains("plate_opacity")); assert!(updated.contains("0.85"));
// 4. Parse plate_opacity when present (should return written value 0.85)
let val2 = parse_f32_from(&updated, "plate_opacity", 1.0);
@@ -5065,7 +5015,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse plate_corner_radius when missing (should return default 12)
@@ -5076,7 +5026,7 @@ mod tests {
// 3. Write plate_corner_radius config
assert!(write_config_value_path(path_str, "plate_corner_radius", "16"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"plate_corner_radius\": 16"));
+ assert!(updated.contains("plate_corner_radius")); assert!(updated.contains("16"));
// 4. Parse plate_corner_radius when present (should return written value 16)
let val2 = parse_u16_from(&updated, "plate_corner_radius", 12);
@@ -5095,7 +5045,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse color_selector_height when missing (should return default 22)
@@ -5106,7 +5056,7 @@ mod tests {
// 3. Write color_selector_height config
assert!(write_config_value_path(path_str, "color_selector_height", "28"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"color_selector_height\": 28"));
+ assert!(updated.contains("color_selector_height")); assert!(updated.contains("28"));
// 4. Parse color_selector_height when present (should return written value 28)
let val2 = parse_u16_from(&updated, "color_selector_height", 22);
@@ -5123,7 +5073,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse font_selector_corner_radius when missing (should return default 4)
@@ -5134,7 +5084,7 @@ mod tests {
// 3. Write font_selector_corner_radius config
assert!(write_config_value_path(path_str, "font_selector_corner_radius", "8"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"font_selector_corner_radius\": 8"));
+ assert!(updated.contains("font_selector_corner_radius")); assert!(updated.contains("8"));
// 4. Parse font_selector_corner_radius when present (should return written value 8)
let val2 = parse_u16_from(&updated, "font_selector_corner_radius", 4);
@@ -5151,7 +5101,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse textbox_corner_radius when missing (should return default 4)
@@ -5162,7 +5112,7 @@ mod tests {
// 3. Write textbox_corner_radius config
assert!(write_config_value_path(path_str, "textbox_corner_radius", "8"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"textbox_corner_radius\": 8"));
+ assert!(updated.contains("textbox_corner_radius")); assert!(updated.contains("8"));
// 4. Parse textbox_corner_radius when present (should return written value 8)
let val2 = parse_u16_from(&updated, "textbox_corner_radius", 4);
@@ -5179,7 +5129,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse textbox_height when missing (should return default 44)
@@ -5190,7 +5140,7 @@ mod tests {
// 3. Write textbox_height config
assert!(write_config_value_path(path_str, "textbox_height", "48"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"textbox_height\": 48"));
+ assert!(updated.contains("textbox_height")); assert!(updated.contains("48"));
// 4. Parse textbox_height when present (should return written value 48)
let val2 = parse_u16_from(&updated, "textbox_height", 44);
@@ -5207,7 +5157,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse color_selector_font when missing (should return default "monospace")
@@ -5218,7 +5168,8 @@ mod tests {
// 3. Write color_selector_font config
assert!(write_config_value_path(path_str, "color_selector_font", "\"Berkeley Mono\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains(r#""color_selector_font": "Berkeley Mono""#));
+ assert!(updated.contains("color_selector_font"));
+ assert!(updated.contains("Berkeley Mono"));
// 4. Parse color_selector_font when present (should return written value)
let val2 = parse_string_from(&updated, "color_selector_font", "monospace");
@@ -5235,7 +5186,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse menubar_font when missing (should return default "Outfit")
@@ -5246,7 +5197,8 @@ mod tests {
// 3. Write menubar_font config
assert!(write_config_value_path(path_str, "menubar_font", "\"Inter\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains(r#""menubar_font": "Inter""#));
+ assert!(updated.contains("menubar_font"));
+ assert!(updated.contains("Inter"));
// 4. Parse menubar_font when present (should return written value)
let val2 = parse_string_from(&updated, "menubar_font", "Outfit");
@@ -5263,7 +5215,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse font_selector_height when missing (should return default 44)
@@ -5274,7 +5226,7 @@ mod tests {
// 3. Write font_selector_height config
assert!(write_config_value_path(path_str, "font_selector_height", "48"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"font_selector_height\": 48"));
+ assert!(updated.contains("font_selector_height")); assert!(updated.contains("48"));
// 4. Parse font_selector_height when present (should return written value 48)
let val2 = parse_u16_from(&updated, "font_selector_height", 44);
@@ -5291,7 +5243,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse grid_min_col_width when missing (should return default 260)
@@ -5302,7 +5254,7 @@ mod tests {
// 3. Write grid_min_col_width config
assert!(write_config_value_path(path_str, "grid_min_col_width", "280"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"grid_min_col_width\": 280"));
+ assert!(updated.contains("grid_min_col_width")); assert!(updated.contains("280"));
// 4. Parse grid_min_col_width when present (should return written value 280)
let val2 = parse_u16_from(&updated, "grid_min_col_width", 260);
@@ -5319,7 +5271,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse grid_gap when missing (should return default 8)
@@ -5330,7 +5282,7 @@ mod tests {
// 3. Write grid_gap config
assert!(write_config_value_path(path_str, "grid_gap", "12"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"grid_gap\": 12"));
+ assert!(updated.contains("grid_gap")); assert!(updated.contains("12"));
// 4. Parse grid_gap when present (should return written value 12)
let val2 = parse_u16_from(&updated, "grid_gap", 8);
@@ -5347,7 +5299,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse color_selector_preview_corner_radius when missing (should return default 4)
@@ -5358,7 +5310,7 @@ mod tests {
// 3. Write color_selector_preview_corner_radius config
assert!(write_config_value_path(path_str, "color_selector_preview_corner_radius", "8"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"color_selector_preview_corner_radius\": 8"));
+ assert!(updated.contains("color_selector_preview_corner_radius")); assert!(updated.contains("8"));
// 4. Parse color_selector_preview_corner_radius when present (should return written value 8)
let val2 = parse_u16_from(&updated, "color_selector_preview_corner_radius", 4);
@@ -5375,7 +5327,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse color_selector_corner_radius when missing (should return default 4)
@@ -5386,7 +5338,7 @@ mod tests {
// 3. Write color_selector_corner_radius config
assert!(write_config_value_path(path_str, "color_selector_corner_radius", "6"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"color_selector_corner_radius\": 6"));
+ assert!(updated.contains("color_selector_corner_radius")); assert!(updated.contains("6"));
// 4. Parse color_selector_corner_radius when present (should return written value 6)
let val2 = parse_u16_from(&updated, "color_selector_corner_radius", 4);
@@ -5403,7 +5355,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse color_selector_preview_margin when missing (should return default 0)
@@ -5414,7 +5366,7 @@ mod tests {
// 3. Write color_selector_preview_margin config
assert!(write_config_value_path(path_str, "color_selector_preview_margin", "3"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"color_selector_preview_margin\": 3"));
+ assert!(updated.contains("color_selector_preview_margin")); assert!(updated.contains("3"));
// 4. Parse color_selector_preview_margin when present (should return written value 3)
let val2 = parse_u16_from(&updated, "color_selector_preview_margin", 0);
@@ -5432,7 +5384,7 @@ mod tests {
let path = dir.join("test_button_padding_config.toml");
let path_str = path.to_str().unwrap();
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
let content = fs::read_to_string(path_str).unwrap();
@@ -5441,7 +5393,7 @@ mod tests {
assert!(write_config_value_path(path_str, "button_padding", "20"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"button_padding\": 20"));
+ assert!(updated.contains("button_padding")); assert!(updated.contains("20"));
let val2 = parse_u16_from(&updated, "button_padding", 14);
assert_eq!(val2, 20);
@@ -5455,7 +5407,7 @@ mod tests {
let path = dir.join("test_button_strip_spacing_config.toml");
let path_str = path.to_str().unwrap();
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
let content = fs::read_to_string(path_str).unwrap();
@@ -5464,7 +5416,7 @@ mod tests {
assert!(write_config_value_path(path_str, "button_strip_spacing", "12"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"button_strip_spacing\": 12"));
+ assert!(updated.contains("button_strip_spacing")); assert!(updated.contains("12"));
let val2 = parse_u16_from(&updated, "button_strip_spacing", 8);
assert_eq!(val2, 12);
@@ -5479,7 +5431,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse slider_height when missing (should return default 28)
@@ -5490,7 +5442,7 @@ mod tests {
// 3. Write slider_height config
assert!(write_config_value_path(path_str, "slider_height", "32"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"slider_height\": 32"));
+ assert!(updated.contains("slider_height")); assert!(updated.contains("32"));
// 4. Parse slider_height when present (should return written value 32)
let val2 = parse_u16_from(&updated, "slider_height", 28);
@@ -5507,7 +5459,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse when missing (should return default 0)
@@ -5518,7 +5470,7 @@ mod tests {
// 3. Write alignment config
assert!(write_config_value_path(path_str, "nested_section_label_alignment", "2"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"nested_section_label_alignment\": 2"));
+ assert!(updated.contains("nested_section_label_alignment")); assert!(updated.contains("2"));
// 4. Parse when present (should return written value 2)
let val2 = parse_u16_from(&updated, "nested_section_label_alignment", 0);
@@ -5535,7 +5487,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse when missing (should return default 0)
@@ -5546,7 +5498,7 @@ mod tests {
// 3. Write alignment config
assert!(write_config_value_path(path_str, "nested_section_label_offset", "-15"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"nested_section_label_offset\": -15"));
+ assert!(updated.contains("nested_section_label_offset")); assert!(updated.contains("-15"));
// 4. Parse when present (should return written value -15)
let val2 = parse_i16_from(&updated, "nested_section_label_offset", 0);
@@ -5563,7 +5515,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse dropdown_height when missing (should return default 44)
@@ -5574,7 +5526,7 @@ mod tests {
// 3. Write dropdown_height config
assert!(write_config_value_path(path_str, "dropdown_height", "48"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"dropdown_height\": 48"));
+ assert!(updated.contains("dropdown_height")); assert!(updated.contains("48"));
// 4. Parse dropdown_height when present (should return written value 48)
let val2 = parse_u16_from(&updated, "dropdown_height", 44);
@@ -5591,7 +5543,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse dropdown_corner_radius when missing (should return default 4)
@@ -5602,7 +5554,7 @@ mod tests {
// 3. Write dropdown_corner_radius config
assert!(write_config_value_path(path_str, "dropdown_corner_radius", "12"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"dropdown_corner_radius\": 12"));
+ assert!(updated.contains("dropdown_corner_radius")); assert!(updated.contains("12"));
// 4. Parse dropdown_corner_radius when present (should return written value 12)
let val2 = parse_u16_from(&updated, "dropdown_corner_radius", 4);
@@ -5619,7 +5571,7 @@ mod tests {
let path_str = path.to_str().unwrap();
// 1. Initial configuration
- let initial_content = "{\"layout\": {\"gap\": 18, \"border_color\": \"#374673\"}}";
+ let initial_content = "layout {\n gap (i64)18\n border_color (color)\"#374673\"\n}\n";
fs::write(path_str, initial_content).unwrap();
// 2. Parse when missing (should return default 6)
@@ -5630,7 +5582,7 @@ mod tests {
// 3. Write label_margin config
assert!(write_config_value_path(path_str, "label_margin", "12"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"label_margin\": 12"));
+ assert!(updated.contains("label_margin")); assert!(updated.contains("12"));
// 4. Parse when present (should return written value 12)
let val2 = parse_u16_from(&updated, "label_margin", 6);
@@ -5677,7 +5629,7 @@ mod tests {
// 3. Write button_corner_radius config
assert!(write_config_value_path(path_str, "button_corner_radius", "12"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"button_corner_radius\": 12"));
+ assert!(updated.contains("button_corner_radius")); assert!(updated.contains("12"));
// 4. Parse when present (should return written value 12)
let val2 = parse_u16_from(&updated, "button_corner_radius", 4);
@@ -5705,7 +5657,7 @@ mod tests {
// 3. Write opacity config
write_notifications_config_value_path(path_str, "opacity", "0.85");
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"opacity\": 0.85"));
+ assert!(updated.contains("opacity")); assert!(updated.contains("0.85"));
// 4. Parse opacity when present (should return 0.85)
let opacity2 = parse_notifications_opacity(&updated);
@@ -5714,7 +5666,7 @@ mod tests {
// 5. Write bg_color config
write_notifications_config_value_path(path_str, "bg_color", "\"#112233\"");
let updated2 = fs::read_to_string(path_str).unwrap();
- assert!(updated2.contains("\"bg_color\": \"#112233\""));
+ assert!(updated2.contains("bg_color")); assert!(updated2.contains("#112233"));
// 6. Parse bg_color when present
let bg_color = parse_notifications_color(&updated2, "bg_color", [0, 0, 0]);
@@ -5746,7 +5698,7 @@ mod tests {
}"#;
fs::write(&links_path, test_links).unwrap();
- let initial_content = "{\"layout\": {\"spinbox_height\": 28, \"textbox_height\": 28, \"dropdown_height\": 28, \"button_corner_radius\": 4}}";
+ let initial_content = "layout {\n spinbox_height (i64)28\n textbox_height (i64)28\n dropdown_height (i64)28\n button_corner_radius (i64)4\n}\n";
fs::write(&config_path, initial_content).unwrap();
TEST_CONFIG_PATH.with(|p| *p.borrow_mut() = Some(config_path_str));
@@ -5758,10 +5710,10 @@ mod tests {
TEST_LINKS_PATH.with(|p| *p.borrow_mut() = None);
let updated = fs::read_to_string(&config_path).unwrap();
- assert!(updated.contains("\"spinbox_height\": 32"));
- assert!(updated.contains("\"textbox_height\": 32"));
- assert!(updated.contains("\"dropdown_height\": 32"));
- assert!(updated.contains("\"button_corner_radius\": 4"));
+ assert!(updated.contains("spinbox_height")); assert!(updated.contains("32"));
+ assert!(updated.contains("textbox_height")); assert!(updated.contains("32"));
+ assert!(updated.contains("dropdown_height")); assert!(updated.contains("32"));
+ assert!(updated.contains("button_corner_radius")); assert!(updated.contains("4"));
let _ = fs::remove_file(config_path);
let _ = fs::remove_file(links_path);
@@ -5776,7 +5728,7 @@ mod tests {
let config_path_str = config_path.to_str().unwrap().to_string();
let links_path_str = links_path.to_str().unwrap().to_string();
- let test_config = "{\"layout\": {\"spinbox_height\": 28, \"textbox_height\": 28, \"dropdown_height\": 28}}";
+ let test_config = "layout {\n spinbox_height (i64)28\n textbox_height (i64)28\n dropdown_height (i64)28\n}\n";
fs::write(&config_path, test_config).unwrap();
let test_links = r#"{
@@ -5832,7 +5784,7 @@ mod tests {
// 5. Write surfaces backplate_color config
write_surfaces_config_value_path(path_str, "backplate_color", "\"#112233\"");
let updated2 = fs::read_to_string(path_str).unwrap();
- assert!(updated2.contains("\"backplate_color\": \"#112233\""));
+ assert!(updated2.contains("backplate_color")); assert!(updated2.contains("#112233"));
// 6. Parse surfaces backplate_color when present
let color2 = parse_surfaces_color(&updated2, "backplate_color", [0, 0, 0]);
@@ -5841,7 +5793,7 @@ mod tests {
// 7. Write surfaces backplate_corner_radius config
write_surfaces_config_value_path(path_str, "backplate_corner_radius", "16");
let updated3 = fs::read_to_string(path_str).unwrap();
- assert!(updated3.contains("\"backplate_corner_radius\": 16"));
+ assert!(updated3.contains("backplate_corner_radius")); assert!(updated3.contains("16"));
// 8. Parse surfaces backplate_corner_radius when present
let radius2 = parse_surfaces_u16(&updated3, "backplate_corner_radius", 12);
@@ -5850,7 +5802,7 @@ mod tests {
// 9. Write surfaces desktop_background config
write_surfaces_config_value_path(path_str, "desktop_background", "\"#445566\"");
let updated4 = fs::read_to_string(path_str).unwrap();
- assert!(updated4.contains("\"desktop_background\": \"#445566\""));
+ assert!(updated4.contains("desktop_background")); assert!(updated4.contains("#445566"));
// 10. Parse surfaces desktop_background when present
let color3 = parse_surfaces_color(&updated4, "desktop_background", [0, 0, 0]);
@@ -5875,7 +5827,7 @@ mod tests {
assert!(write_config_value_path(path_str, "page_opacity", "0.75"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"page_opacity\": 0.75"));
+ assert!(updated.contains("page_opacity")); assert!(updated.contains("0.75"));
let val2 = parse_f32_from(&updated, "page_opacity", 1.0);
assert_eq!(val2, 0.75);
@@ -5898,7 +5850,7 @@ mod tests {
assert!(write_config_value_path(path_str, "layer_opacity", "0.60"));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"layer_opacity\": 0.6"));
+ assert!(updated.contains("layer_opacity")); assert!(updated.contains("0.6"));
let val2 = parse_f32_from(&updated, "layer_opacity", 1.0);
assert_eq!(val2, 0.60);
@@ -5921,7 +5873,7 @@ mod tests {
assert!(write_config_value_path(path_str, "page_color", "\"#112233\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"page_color\": \"#112233\""));
+ assert!(updated.contains("page_color")); assert!(updated.contains("#112233"));
let color2 = parse_color_from_key(&updated, "page_color", [0, 0, 0]);
assert_eq!(color2, [17, 34, 51]);
@@ -5944,7 +5896,7 @@ mod tests {
assert!(write_config_value_path(path_str, "layer_color", "\"#445566\""));
let updated = fs::read_to_string(path_str).unwrap();
- assert!(updated.contains("\"layer_color\": \"#445566\""));
+ assert!(updated.contains("layer_color")); assert!(updated.contains("#445566"));
let color2 = parse_color_from_key(&updated, "layer_color", [0, 0, 0]);
assert_eq!(color2, [68, 85, 102]);
diff --git a/src/pages/storage.rs b/src/pages/storage.rs
index 887ff67..4ffaed8 100644
--- a/src/pages/storage.rs
+++ b/src/pages/storage.rs
@@ -43,7 +43,7 @@ pub enum StorageMessage {
}
fn status_path() -> String {
- format!("{}/.config/cce-system-settings/backup_status.txt", std::env::var("HOME").unwrap_or_default())
+ format!("{}/.config/cce/cce-settings/backup_status.txt", std::env::var("HOME").unwrap_or_default())
}
pub fn read_backup_status() -> (String, String, Option<String>) {
@@ -111,7 +111,7 @@ pub async fn fetch_storage_state() -> StorageState {
pub async fn run_backup() -> Result<(String, String), String> {
// Run the backup system helper script via pkexec (graphical auth prompt)
let output = tokio::process::Command::new("pkexec")
- .arg("/home/lsgalante/.local/share/cce-system-settings/helpers/backup-system.sh")
+ .arg("/home/lsgalante/.local/share/cce-settings/helpers/backup-system.sh")
.output()
.await
.map_err(|e| format!("Failed to run backup script: {}", e))?;
diff --git a/src/pages/system_info.rs b/src/pages/system_info.rs
index 03b851b..47a9878 100644
--- a/src/pages/system_info.rs
+++ b/src/pages/system_info.rs
@@ -176,14 +176,14 @@ fn format_duration(secs: i64) -> String {
fn spawn_cpu_power(powersave: bool) {
let script = if powersave { "cpu-powersave-on" } else { "cpu-powersave-off" };
let mut cmd = std::process::Command::new("pkexec");
- cmd.arg(format!("/home/lsgalante/.local/share/cce-system-settings/helpers/{}", script));
+ cmd.arg(format!("/home/lsgalante/.local/share/cce-settings/helpers/{}", script));
let _ = cce_ui::process::spawn_detached(cmd);
}
fn spawn_gpu_power(powersave: bool) {
let script = if powersave { "gpu-powersave-on" } else { "gpu-powersave-off" };
let mut cmd = std::process::Command::new("pkexec");
- cmd.arg(format!("/home/lsgalante/.local/share/cce-system-settings/helpers/{}", script));
+ cmd.arg(format!("/home/lsgalante/.local/share/cce-settings/helpers/{}", script));
let _ = cce_ui::process::spawn_detached(cmd);
}
@@ -776,7 +776,7 @@ pub fn read_notifications_config() -> NotificationsConfig {
}
fn parse_json(content: &str) -> serde_json::Value {
- serde_json::from_str(content).unwrap_or_default()
+ cce_ui::config::parse_kdl_to_json(content)
}
fn parse_notifications_enable(content: &str) -> bool {
@@ -904,12 +904,12 @@ fn get_config_path() -> String {
if let Some(path) = p.borrow().as_ref() {
return path.clone();
}
- "/home/lsgalante/.config/cce/config.json".to_string()
+ "/home/lsgalante/.config/cce/config.kdl".to_string()
})
}
#[cfg(not(test))]
{
- "/home/lsgalante/.config/cce/config.json".to_string()
+ "/home/lsgalante/.config/cce/config.kdl".to_string()
}
}
@@ -937,39 +937,31 @@ mod tests {
#[test]
fn test_parse_notifications_enable_explicit() {
- let content = "{\"notifications\": {\"enable\": false}}";
+ let content = "notifications {\n enable (bool)false\n}\n";
assert!(!parse_notifications_enable(content));
- let content = "{\"notifications\": {\"enable\": true}}";
+ let content = "notifications {\n enable (bool)true\n}\n";
assert!(parse_notifications_enable(content));
}
#[test]
fn test_parse_notifications_enable_other_sections() {
- let content = r#"{
- "layout": {"enable": false},
- "notifications": {"enable": true},
- "input": {"enable": false}
- }"#;
+ let content = "layout {\n enable (bool)false\n}\nnotifications {\n enable (bool)true\n}\ninput {\n enable (bool)false\n}\n";
assert!(parse_notifications_enable(content));
- let content = r#"{
- "layout": {"enable": true},
- "notifications": {"enable": false},
- "input": {"enable": true}
- }"#;
+ let content = "layout {\n enable (bool)true\n}\nnotifications {\n enable (bool)false\n}\ninput {\n enable (bool)true\n}\n";
assert!(!parse_notifications_enable(content));
}
#[test]
fn test_parse_notifications_duration_default() {
assert_eq!(parse_notifications_duration(""), 5);
- assert_eq!(parse_notifications_duration("{\"notifications\": {}}"), 5);
+ assert_eq!(parse_notifications_duration("notifications {}"), 5);
}
#[test]
fn test_parse_notifications_duration_explicit() {
- let content = "{\"notifications\": {\"duration\": 10}}";
+ let content = "notifications {\n duration (i64)10\n}\n";
assert_eq!(parse_notifications_duration(content), 10);
}
diff --git a/src/renderer.rs b/src/renderer.rs
index d31aab4..5747a3d 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -1,6 +1,6 @@
use crate::{SystemInterface, AppWidget, make_text_buffer, make_text_buffer_with_font};
-use cce_system_settings::app::PageContent;
-use cce_system_settings::pages::Page;
+use cce_settings::app::PageContent;
+use cce_settings::pages::Page;
use cce_ui::widget::{Element, TextItem, PageSelector};
impl SystemInterface {
diff --git a/src/watchers.rs b/src/watchers.rs
index c4c3adf..b0487e8 100644
--- a/src/watchers.rs
+++ b/src/watchers.rs
@@ -107,7 +107,7 @@ pub fn spawn_all(
Some(t) => t.elapsed() >= std::time::Duration::from_secs(30),
};
if should_fetch {
- let mtime = std::fs::metadata("/home/lsgalante/.config/cce/config.json")
+ let mtime = std::fs::metadata("/home/lsgalante/.config/cce/config.kdl")
.and_then(|m| m.modified())
.unwrap_or_else(|_| std::time::SystemTime::now());
let val = tokio::task::spawn_blocking(|| input::read_input_config()).await;
@@ -203,7 +203,7 @@ pub fn spawn_all(
Some(t) => t.elapsed() >= std::time::Duration::from_secs(30),
};
if should_fetch {
- let mtime = std::fs::metadata("/home/lsgalante/.config/cce/config.json")
+ let mtime = std::fs::metadata("/home/lsgalante/.config/cce/config.kdl")
.and_then(|m| m.modified())
.unwrap_or_else(|_| std::time::SystemTime::now());
let val = tokio::task::spawn_blocking(|| interface::read_interface_config()).await;