Add configurable native glass window backgrounds

This commit is contained in:
karl committed 2026-10-13 10:12:25 +02:00
1 parent 19d949fd13
commit 981991bac0
14 files changed
+687 -5

No files matched your search

+50
View File
@@ -7,6 +7,19 @@ use std::{
path::{Path, PathBuf},
};
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BackgroundMaterial {
Solid,
Glass,
#[default]
Frosted,
}
fn default_background_opacity() -> u8 {
90
}
const SETTINGS_VERSION: u32 = 2;
const MAX_SETTINGS_BYTES: u64 = 128 * 1024;
@@ -14,6 +27,10 @@ const MAX_SETTINGS_BYTES: u64 = 128 * 1024;
#[serde(deny_unknown_fields)]
pub struct Settings {
pub version: u32,
#[serde(default)]
pub background_material: BackgroundMaterial,
#[serde(default = "default_background_opacity")]
pub background_opacity: u8,
pub roots: Vec<PathBuf>,
pub cpu_threads: usize,
/// Managed local Google EmbeddingGemma2 artifacts. Older settings default
@@ -26,6 +43,8 @@ impl Default for Settings {
fn default() -> Self {
Self {
version: SETTINGS_VERSION,
background_material: BackgroundMaterial::default(),
background_opacity: default_background_opacity(),
roots: Vec::new(),
cpu_threads: 2,
model_directory: None,
@@ -38,6 +57,9 @@ impl Settings {
if self.version != SETTINGS_VERSION {
return Err(format!("Unsupported settings version {}", self.version));
}
if !(70..=100).contains(&self.background_opacity) {
return Err("Background opacity must be between 70 and 100 percent.".into());
}
if !(1..=8).contains(&self.cpu_threads) {
return Err("CPU threads must be between 1 and 8.".into());
}
@@ -229,3 +251,31 @@ mod budget_migration_tests {
assert_eq!(SettingsStore::load(path).unwrap().value.cpu_threads, 8);
}
}
#[cfg(test)]
mod appearance_tests {
use super::*;
#[test]
fn legacy_defaults_and_saved_appearance_round_trip() {
let directory = tempfile::tempdir().unwrap();
let path = directory.path().join("settings.json");
fs::write(&path, r#"{"version":2,"roots":[],"cpu_threads":2}"#).unwrap();
let mut store = SettingsStore::load(path.clone()).unwrap();
assert_eq!(store.value.background_material, BackgroundMaterial::Frosted);
assert_eq!(store.value.background_opacity, 90);
let mut next = store.value.clone();
next.background_material = BackgroundMaterial::Glass;
next.background_opacity = 70;
store.save(next.clone()).unwrap();
assert_eq!(SettingsStore::load(path.clone()).unwrap().value, next);
let bytes = fs::read(&path).unwrap();
for opacity in [0, 69, 101, 255] {
let mut invalid = next.clone();
invalid.background_opacity = opacity;
assert!(store.save(invalid).is_err());
assert_eq!(store.value, next);
assert_eq!(fs::read(&path).unwrap(), bytes);
}
assert!(serde_json::from_str::<BackgroundMaterial>("\"other\"").is_err());
}
}