Rust · 4009 bytes Raw Blame History
1 //! Greeter configuration
2 //!
3 //! Loads visual settings, theming, and accessibility options.
4
5 use crate::theme::{AccessibilityConfig, Theme, ThemeConfig};
6 use anyhow::{Context, Result};
7 use serde::Deserialize;
8 use std::path::PathBuf;
9
10 /// Main greeter configuration
11 #[derive(Debug, Deserialize, Default)]
12 pub struct GreeterConfig {
13 #[serde(default)]
14 pub visual: VisualConfig,
15 #[serde(default)]
16 pub garbg: GarbgIntegration,
17 #[serde(default)]
18 pub theme: ThemeConfig,
19 #[serde(default)]
20 pub accessibility: AccessibilityConfig,
21 }
22
23 /// Visual appearance settings
24 #[derive(Debug, Deserialize)]
25 pub struct VisualConfig {
26 /// Blur radius for background
27 #[serde(default = "default_blur_radius")]
28 pub blur_radius: f32,
29
30 /// Background brightness (0.0-1.0, lower = darker)
31 #[serde(default = "default_brightness")]
32 pub brightness: f32,
33
34 /// Corner radius for UI elements
35 #[serde(default = "default_corner_radius")]
36 pub corner_radius: f64,
37
38 /// Fade-out duration in milliseconds when starting session
39 #[serde(default = "default_fade_duration")]
40 pub fade_duration_ms: u64,
41 }
42
43 impl Default for VisualConfig {
44 fn default() -> Self {
45 Self {
46 blur_radius: default_blur_radius(),
47 brightness: default_brightness(),
48 corner_radius: default_corner_radius(),
49 fade_duration_ms: default_fade_duration(),
50 }
51 }
52 }
53
54 /// garbg integration settings
55 #[derive(Debug, Deserialize)]
56 pub struct GarbgIntegration {
57 /// Whether to use garbg wallpaper
58 #[serde(default = "default_true")]
59 pub enabled: bool,
60
61 /// Fallback wallpaper if garbg not configured
62 #[serde(default = "default_fallback")]
63 pub fallback: String,
64 }
65
66 impl Default for GarbgIntegration {
67 fn default() -> Self {
68 Self {
69 enabled: default_true(),
70 fallback: default_fallback(),
71 }
72 }
73 }
74
75 fn default_blur_radius() -> f32 {
76 25.0
77 }
78 fn default_brightness() -> f32 {
79 0.6
80 }
81 fn default_corner_radius() -> f64 {
82 16.0
83 }
84 fn default_fade_duration() -> u64 {
85 200
86 }
87 fn default_true() -> bool {
88 true
89 }
90 fn default_fallback() -> String {
91 // Try common locations for a default wallpaper
92 let candidates = [
93 "/home/mfwolffe/Pictures/background/cold/a_snowy_mountain_with_clouds_above.jpg",
94 "/usr/share/backgrounds/default.png",
95 "/usr/share/gardm/backgrounds/default.jpg",
96 ];
97 for path in candidates {
98 if std::path::Path::new(path).exists() {
99 return path.to_string();
100 }
101 }
102 "/usr/share/gardm/backgrounds/default.jpg".to_string()
103 }
104
105 impl GreeterConfig {
106 /// Load configuration from file or use defaults
107 pub fn load() -> Result<Self> {
108 // Try system config location
109 let config_paths = [
110 PathBuf::from("/etc/gardm/greeter.toml"),
111 PathBuf::from("/usr/share/gardm/greeter.toml"),
112 ];
113
114 for path in &config_paths {
115 if path.exists() {
116 let content = std::fs::read_to_string(path)
117 .with_context(|| format!("Failed to read config from {:?}", path))?;
118 let config: GreeterConfig = toml::from_str(&content)
119 .with_context(|| format!("Failed to parse config from {:?}", path))?;
120 tracing::info!("Loaded greeter config from {:?}", path);
121 return Ok(config);
122 }
123 }
124
125 // Use defaults
126 tracing::debug!("No config file found, using defaults");
127 Ok(Self::default())
128 }
129
130 /// Build the theme from config, applying accessibility options
131 pub fn build_theme(&self) -> Theme {
132 self.theme.clone().into_theme(&self.accessibility)
133 }
134
135 /// Get effective fade duration (0 if reduce_motion is enabled)
136 pub fn effective_fade_duration(&self) -> u64 {
137 if self.accessibility.reduce_motion {
138 0
139 } else {
140 self.visual.fade_duration_ms
141 }
142 }
143 }
144