Skip to content

Commit 489c3bf

Browse files
committed
feat: Render tray icon colors using theme colors.
1 parent 3f48e16 commit 489c3bf

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

src-tauri/src/commands.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ pub fn settings_reset_defaults(
180180

181181
timer.apply_settings(new_settings.clone());
182182
*tray_state.countdown_mode.lock().unwrap() = new_settings.dial_countdown;
183+
let data_dir = app.path().app_data_dir().map_err(|e| e.to_string())?;
184+
if let Some(theme) = themes::find(&data_dir, &new_settings.theme) {
185+
*tray_state.colors.lock().unwrap() = tray::TrayColors::from_colors_map(&theme.colors);
186+
}
183187
app.emit("settings:changed", &new_settings).ok();
184188
Ok(new_settings)
185189
}
@@ -205,6 +209,8 @@ pub fn theme_apply(
205209
name: String,
206210
app: AppHandle,
207211
db: State<'_, DbState>,
212+
tray_state: State<'_, Arc<TrayState>>,
213+
timer: State<'_, TimerController>,
208214
) -> Result<Theme, String> {
209215
let data_dir = app
210216
.path()
@@ -221,6 +227,16 @@ pub fn theme_apply(
221227
settings::load(&conn).map_err(|e| e.to_string())?
222228
};
223229

230+
// Update tray colors and immediately re-render the icon for the new theme.
231+
*tray_state.colors.lock().unwrap() = tray::TrayColors::from_colors_map(&theme.colors);
232+
let snap = timer.get_snapshot();
233+
let progress = if snap.total_secs > 0 {
234+
snap.elapsed_secs as f32 / snap.total_secs as f32
235+
} else {
236+
0.0
237+
};
238+
tray::update_icon(&tray_state, &snap.round_type, snap.is_paused, progress);
239+
224240
// Notify all windows so they can re-apply the new theme CSS.
225241
app.emit("settings:changed", &updated_settings).ok();
226242

src-tauri/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ pub fn run() {
5555
settings::load(&conn).expect("failed to load settings")
5656
};
5757

58-
// Sync tray countdown mode from saved settings.
58+
// Sync tray state from saved settings.
5959
*tray_state.countdown_mode.lock().unwrap() = initial_settings.dial_countdown;
60+
if let Some(theme) = themes::find(&app_data_dir, &initial_settings.theme) {
61+
*tray_state.colors.lock().unwrap() = tray::TrayColors::from_colors_map(&theme.colors);
62+
}
6063

6164
// --- Audio engine (optional — graceful if no audio device) ---
6265
if let Some(audio) = audio::AudioManager::new(&initial_settings) {

src-tauri/src/tray/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ impl Default for TrayColors {
4545
}
4646
}
4747

48+
impl TrayColors {
49+
/// Build a `TrayColors` from a theme's CSS-variable color map.
50+
/// Falls back to `TrayColors::default()` values for any key that is
51+
/// missing or unparseable.
52+
pub fn from_colors_map(colors: &std::collections::HashMap<String, String>) -> Self {
53+
let d = Self::default();
54+
let get = |key: &str, fallback: [u8; 4]| {
55+
colors.get(key)
56+
.and_then(|hex| parse_hex_color(hex))
57+
.unwrap_or(fallback)
58+
};
59+
Self {
60+
background: get("--color-background", d.background),
61+
focus_round: get("--color-focus-round", d.focus_round),
62+
short_round: get("--color-short-round", d.short_round),
63+
long_round: get("--color-long-round", d.long_round),
64+
foreground: get("--color-foreground", d.foreground),
65+
}
66+
}
67+
}
68+
4869
/// Parse a CSS hex color (#RRGGBB or #RRGGBBAA) into [r, g, b, a].
4970
pub fn parse_hex_color(hex: &str) -> Option<[u8; 4]> {
5071
let h = hex.strip_prefix('#')?;

0 commit comments

Comments
 (0)